zoukankan      html  css  js  c++  java
  • 洛谷P3567[POI2014]KUR-Couriers(主席树+二分)

    题意:给一个数列,每次询问一个区间内有没有一个数出现次数超过一半

    题解:

    最近比赛太多,都没时间切水题了,刚好日推了道主席树裸题,就写了一下

    然后

    WA80

    WA80

    WA0

    WA90

    WA80

    ??????

    结果重新审题发现没有数据范围????

    哦,原来是500000,我是真的菜

    因为必须要一个数出现超过一半

    所以这个数肯定会在左子树和右子树中总个数和较大的那个里。

    显然这样二分找到树底复杂度是logn的

    如果此时树底这个点的数值大于一半,那么就输出这个解,否则puts("0")

    以及:不用离散化!!!

    代码如下:

    #include<bits/stdc++.h>
    #define lson tr[now].l
    #define rson tr[now].r
    using namespace std;
    
    struct tree
    {
        int l,r,sum,val;
    }tr[10000050];
    
    int rt[500010],a[500010],n,m,cnt;
    map<int,int> mm;
    
    inline int push_up(int now)
    {
        tr[now].sum=tr[lson].sum+tr[rson].sum;
    }
    
    int insert(int &now,int fa,int l,int r,int pos)
    {
        if(!now) now=++cnt;
        if(l==r)
        {
            tr[now].sum=tr[fa].sum+1;
            tr[now].val=l;
            return 0;
        }
        register int mid=(l+r)>>1;
        if(pos<=mid)
        {
            insert(tr[now].l,tr[fa].l,l,mid,pos);
            tr[now].r=tr[fa].r;
        }
        else
        {
            tr[now].l=tr[fa].l;
            insert(tr[now].r,tr[fa].r,mid+1,r,pos);
        }
        push_up(now);
    }
    
    inline int query(int a,int b,int l,int r,int tar)
    {
        if(l==r)
        {
            if(tr[a].sum-tr[b].sum>=tar) return l;
            else return 0;
        }
        register int mid=(l+r)>>1;
        register int ls=tr[tr[a].l].sum-tr[tr[b].l].sum;
        register int rs=tr[tr[a].r].sum-tr[tr[b].r].sum;
        if(ls>rs) return query(tr[a].l,tr[b].l,l,mid,tar);
        else return query(tr[a].r,tr[b].r,mid+1,r,tar);
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&a[i]);
            insert(rt[i],rt[i-1],1,500000,a[i]);
        }
        int from,to;
        while(m--)
        {
            scanf("%d%d",&from,&to);
            register int mid=(to-from+1)/2+1;
            printf("%d
    ",b[query(rt[to],rt[from-1],1,500000,mid)]);
        }
    }
  • 相关阅读:
    [面试没答上的问题1]http请求,请求头和响应头都有什么信息?
    模拟进度条发现的彩蛋
    实现JavaScript forEach
    JavaScript实现动画效果
    Contents Of My Blogs
    阅读笔记-拍出好照片的30个构图基本功
    阅读笔记-李鸿章传
    阅读笔记-人性的弱点
    阅读笔记-XWord:未来进化
    阅读笔记-活法
  • 原文地址:https://www.cnblogs.com/stxy-ferryman/p/9711167.html
Copyright © 2011-2022 走看看