zoukankan      html  css  js  c++  java
  • BZOJ 3524 [Poi2014]Couriers(可持久化线段树)

    【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=3524

    【题目大意】

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

    【题解】

      建立可持久化的权值线段树,对于区间查询,
      在线段树上二分查询R和L-1版本间的数值差符合要求的位置。

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=500010;
    int n,m,i,x,y,z,ans;
    int l[N*40],r[N*40],v[N*40],tot,root[N],a[N],pre[N];
    void read(int&a){
        char ch;while(!((ch=getchar())>='0')&&(ch<='9'));
        a=ch-'0';while(((ch=getchar())>='0')&&(ch<='9'))a*=10,a+=ch-'0';
    }
    int build(int a,int b){
        int x=++tot; v[x]=0;
        if(a==b)return x;
        int mid=(a+b)>>1;
        return l[x]=build(a,mid),r[x]=build(mid+1,b),x;
    }
    // x版本c位置+p,返回更新后版本根节点id 
    int change(int x,int a,int b,int c,int p){
        int y=++tot;v[y]=v[x]+p;
        if(a==b)return y;
        int mid=(a+b)>>1;
        if(c<=mid)l[y]=change(l[x],a,mid,c,p),r[y]=r[x];
        else l[y]=l[x],r[y]=change(r[x],mid+1,b,c,p);
        return y;
    }
    // 查询[lx,rx]区间内超过cnt的数(cnt>=区间长1/2) 
    int query(int lx,int rx,int cnt){
        int L=1,R=n,mid,x,y;
        x=root[lx-1],y=root[rx];
        while(L!=R){
            if(v[y]-v[x]<=cnt)return 0;
            mid=(L+R)>>1;
            if(v[l[y]]-v[l[x]]>cnt)R=mid,x=l[x],y=l[y];
            else if(v[r[y]]-v[r[x]]>cnt)L=mid+1,x=r[x],y=r[y];
            else return 0;
        }return L;
    }
    int main(){
        while(~scanf("%d%d",&n,&m)){
            root[tot=0]=build(1,n);
            for(int i=1;i<=n;i++){
                int x; read(x);
                root[i]=change(root[i-1],1,n,x,1);
            }
            for(int i=1;i<=m;i++){
                int l,r;
                scanf("%d%d",&l,&r);
                printf("%d
    ",query(l,r,(r-l+1)>>1));
            }
        }return 0;
    }
  • 相关阅读:
    Leetcode 349. Intersection of Two Arrays
    hdu 1016 Prime Ring Problem
    map 树木品种
    油田合并
    函数学习
    Leetcode 103. Binary Tree Zigzag Level Order Traversal
    Leetcode 102. Binary Tree Level Order Traversal
    Leetcode 101. Symmetric Tree
    poj 2524 Ubiquitous Religions(宗教信仰)
    pat 1009. 说反话 (20)
  • 原文地址:https://www.cnblogs.com/forever97/p/bzoj3524.html
Copyright © 2011-2022 走看看