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
  • 相关阅读:
    Tomcat 中会话超时的相关配置
    Oracle10g任务调度创建步骤
    Oracle的三种高可用集群方案
    软/硬件负载均衡产品 你知多少?
    Nginx、LVS及HAProxy负载均衡软件的优缺点详解
    java.sql.SQLException: ORA-00604: 递归 SQL 级别 1 出现错误
    TortoiseSVN客户端重新设置用户名和密码
    Linux下oracle数据库启动和关闭操作
    Linux下使用ps命令来查看Oracle相关的进程
    【Kill】两条Linux命令彻底杀死Oracle
  • 原文地址:https://www.cnblogs.com/JKAI/p/7389281.html
Copyright © 2011-2022 走看看