zoukankan      html  css  js  c++  java
  • 【bzoj3524】Couriers——主席树

    Description

    给一个长度为n的序列a。1≤a[i]≤n(n,m<=500000)。
    m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2。如果存在,输出这个数,否则输出0。

    Input

    第一行两个数n,m。
    第二行n个数,a[i]。
    接下来m行,每行两个数l,r,表示询问[l,r]这个区间。

    Output

    m行,每行对应一个答案。

    Sample Input

    7 5
    1 1 3 2 3 4 3
    1 3
    1 4
    3 7
    1 7
    6 6

    Sample Output

    1
    0
    3
    0
    4


    其实这个直接套一下主席树就好了,只不过当二分到l==r时记得判断一下e[rr].sum-e[ll].sum是否大于(r-l+1)/2就好啦。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    const int N=5e5+5;
    using namespace std;
    struct point{
        int rt,sum,ls,rs;
    }e[N*20];
    int a[N],b[N],tot=0,n,m,sz,x,y;
    void build(int &rt,int le,int ri)
    {
        tot++;rt=tot;
        e[rt].sum=0;
        if(le==ri)return ;
        int mid=(le+ri)>>1;
        build(e[rt].ls,le,mid);
        build(e[rt].rs,mid+1,ri);
    }
    void up(int &rt,int l,int r,int last,int p)
    {
        rt=++tot;
        e[rt].ls=e[last].ls;e[rt].rs=e[last].rs;
        e[rt].sum=e[last].sum+1;
        if(l==r)return;
        int mid=(l+r)>>1;
        if(p<=mid)up(e[rt].ls,l,mid,e[last].ls,p);
        else up(e[rt].rs,mid+1,r,e[last].rs,p);
    }
    int query(int ll,int rr,int l,int r,int p)
    {
        if(l==r){if(e[rr].sum-e[ll].sum>=p)return l;else return 0;}
        int mid=(l+r)>>1;
        int d=e[e[rr].ls].sum-e[e[ll].ls].sum;
        if(d>=p)return query(e[ll].ls,e[rr].ls,l,mid,p);
        else return query(e[ll].rs,e[rr].rs,mid+1,r,p);
    }
    void find()
    {
        int ll,rr;
        scanf("%d %d",&ll,&rr);
        int an=query(e[ll-1].rt,e[rr].rt,1,sz,(rr-ll+1)/2+1);
        printf("%d
    ",b[an]);
    }
    int main()
    {
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i];
        sort(b+1,b+n+1);
        sz=unique(b+1,b+n+1)-(b+1);
        build(e[0].rt,1,sz);
        for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+1+sz,a[i])-b;
        for(int i=1;i<=n;i++)up(e[i].rt,1,sz,e[i-1].rt,a[i]);
        while(m--)find();
        return 0;
    }
    bzoj3524
  • 相关阅读:
    结巴分词 0.14 版发布,Python 中文分词库
    Lazarus 1.0.2 发布,Pascal 集成开发环境
    Android全屏 去除标题栏和状态栏
    服务器日志现 Android 4.2 传将添多项新特性
    Percona XtraBackup 2.0.3 发布
    长平狐 Android 强制设置横屏或竖屏 设置全屏
    NetBeans 7.3 Beta 发布,全新的 HTML5 支持
    CppDepend现在已经支持Linux
    GromJS 1.7.18 发布,服务器端的 JavaScript
    Apache OpenWebBeans 1.1.6 发布
  • 原文地址:https://www.cnblogs.com/JKAI/p/7389281.html
Copyright © 2011-2022 走看看