• bzoj 3524: [Poi2014]Couriers


    3524: [Poi2014]Couriers

    Description

    给一个长度为n的序列a。1≤a[i]≤n。
    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

    HINT

    【数据范围】

    n,m≤500000


    2016.7.9重设空间,但未重测!

    /*
        主席树处理+二分查找
        几乎是个模板题,代码很短。
    */
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define maxn 500010
    using namespace std;
    int tot,cnt,n,m,root[maxn];
    int lc[maxn*20],rc[maxn*20],sum[maxn*20];
    void build(int x,int &y,int l,int r,int v){
        tot++;y=tot;
        sum[y]=sum[x]+1;
        if(l==r)return;
        int mid=(l+r)>>1;
        if(v<=mid){
            rc[y]=rc[x];
            build(lc[x],lc[y],l,mid,v);
        }
        else{
            lc[y]=lc[x];
            build(rc[x],rc[y],mid+1,r,v);
        }
    }
    int query(int x,int y){//两个时刻 
        int l=1,r=n,tmp=(y-x+1)/2;
        x=root[x-1];y=root[y];
        while(l!=r){
            if(sum[y]-sum[x]<=tmp)return 0;
            int mid=l+r>>1;
            if(sum[lc[y]]-sum[lc[x]]>tmp){
                r=mid;x=lc[x];y=lc[y];
            }
            else if(sum[rc[y]]-sum[rc[x]]>tmp){
                l=mid+1;x=rc[x];y=rc[y];
            }
            else return 0;
        }
        return l;
    }
    int main(){
        scanf("%d%d",&n,&m);
        int x,y;
        for(int i=1;i<=n;i++){
            scanf("%d",&x);
            build(root[i-1],root[i],1,n,x);
        }
        for(int i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            printf("%d
    ",query(x,y));
        }
    }
    /*
        递归查询
        注意不要把if(l==r)return l;写成
        if(l==r){
            if(sum[l]>k)return l;
            else return 0;
        }
        因为l不是线段树下标,而是区间边界
    */
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define maxn 500010
    using namespace std;
    int tot,cnt,n,m,root[maxn];
    int lc[maxn*20],rc[maxn*20],sum[maxn*20];
    void build(int x,int &y,int l,int r,int v){
        tot++;y=tot;
        sum[y]=sum[x]+1;
        if(l==r)return;
        int mid=(l+r)>>1;
        if(v<=mid){
            rc[y]=rc[x];
            build(lc[x],lc[y],l,mid,v);
        }
        else{
            lc[y]=lc[x];
            build(rc[x],rc[y],mid+1,r,v);
        }
    }
    int query(int x,int y,int l,int r,int k){
        if(l==r)return l;
        int mid=(l+r)>>1;
        int sz=sum[y]-sum[x];
        if(sz<=k)return 0;
        if(sum[lc[y]]-sum[lc[x]]>k)return query(lc[x],lc[y],l,mid,k);
        if(sum[rc[y]]-sum[rc[x]]>k)return query(rc[x],rc[y],mid+1,r,k);
        return 0;
    }
    int main(){
        freopen("Cola.txt","r",stdin);
        scanf("%d%d",&n,&m);
        int x,y;
        for(int i=1;i<=n;i++){
            scanf("%d",&x);
            build(root[i-1],root[i],1,n,x);
        }
        for(int i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            printf("%d
    ",query(root[x-1],root[y],1,n,(y-x+1)/2));
        }
    }
  • 相关阅读:
    SQL Server(00):JSON 函数
    Oracle(00):SQL Developer官方工具 初探
    SQL Server(00):搜索特定的对象
    三星平板SM-T320刷机
    SQL Server(00):聚合函数
    SQL Server(00):日期时间函数
    SQL Server(00):字符串函数
    SQL Server(00):文本和图像函数
    SQL Server(00):数学函数
    SQL Server(00):元数据函数
  • 原文地址:https://www.cnblogs.com/thmyl/p/8044723.html
Copyright © 2020-2023  润新知