POJ 2104 K-th Number 经典主席树

来源:互联网 发布:常熟淘宝摄影培训 编辑:程序博客网 时间:2024/05/01 09:38

可持久化线段树

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int maxn=100005;struct pi{    int sum;    int lson;    int rson;}pp[maxn*18];int root[maxn],tot;void build(int cnt,int l,int r){    pp[cnt].sum=0;    if(l==r) return ;    pp[cnt].lson=tot+1;    tot++;    build(tot,l,(l+r)/2);    pp[cnt].rson=tot+1;    tot++;    build(tot,(l+r)/2+1,r);}void merg(int qq,int cnt,int n,int p,int k){    int le,ri,mid;    le=1;    ri=n;    while(le<=ri){        mid=(le+ri)/2;        pp[cnt]=pp[qq];        pp[cnt].sum+=k;        if (le==ri) break;        if(p<=mid){            pp[cnt].lson=tot+1;            tot++;            ri=mid;            cnt=tot;            qq=pp[qq].lson;        }        else{            pp[cnt].rson=tot+1;            tot++;            le=mid+1;            cnt=tot;            qq=pp[qq].rson;        }    }}int query(int cnt,int le,int ri,int l,int r){    int s=0;    int mid;    if(le>=l&&ri<=r){        return pp[cnt].sum;    }    mid=(le+ri)/2;    if(l<=mid)    s+=query(pp[cnt].lson,le,mid,l,r);    if(r>mid) s+=query(pp[cnt].rson,mid+1,ri,l,r);    return s;}int a[maxn],b[maxn];int get(int l,int r,int n,int k){    int le,ri,mid;    le=1;    ri=n;    while(le<=ri){        mid=(le+ri)/2;        int q=query(root[r],1,n,1,mid)-query(root[l-1],1,n,1,mid);        if(q<k) le=mid+1;        else ri=mid-1;    }    return le;}int main(){    int i,n,m;    while(cin>>n>>m){        root[0]=0;        tot=0;        for(i=1;i<=n;i++){            scanf("%d",&a[i]);            b[i]=a[i];        }        sort(b+1,b+1+n);        for(i=1;i<=n;i++){            a[i]=(int)(lower_bound(b+1,b+1+n,a[i])-b);        }        for(i=1;i<=n;i++){            root[i]=tot+1;            tot++;            merg(root[i-1],root[i],n,a[i],1);        }        for(i=0;i<m;i++){            int a,bb,c;            scanf("%d%d%d",&a,&bb,&c);            printf("%d\n",b[get(a,bb,n,c)]);        }    }}


0 0
原创粉丝点击