1. 程式人生 > >主席樹模板(動態)

主席樹模板(動態)

#include<bits/stdc++.h>

using namespace std;

const int N=2e6+10;

int n,m,sz,tot,a[N],b[N],rt[N],s[N],ls[N*30],rs[N*30],sum[N*30],rootl[40],rootr[40],cntl,cntr;

struct Que{

    int opt,i,j,k;

}q[N];

int get(int x){

    return lower_bound(b+1,b+sz+1,x)-b;

}

int lowbit(int x){

    return x&(-x);

}

struct chairman_of_tree{ void update(int pre,int &o,int l,int r,int x){ o=++tot; ls[o]=ls[pre];rs[o]=rs[pre]; sum[o]=sum[pre]+1; if(l==r) return ; int mid=l+r>>1; if(x<=mid) update(ls[pre],ls[o],l,mid,x); else update(rs[pre],rs[o],mid+1
,r,x); } void arr_update(int &rt,int l,int r,int x,int val){ if(rt==0){ rt=++tot; } sum[rt]+=val; if(l==r) return ; int mid=l+r>>1; if(x<=mid) arr_update(ls[rt],l,mid,x,val); else arr_update(rs[rt],mid+1
,r,x,val); } void arr_update(int k,int val){ int x=get(a[k]),y=get(val); a[k]=val; while(k<=n){ arr_update(s[k],1,sz,x,-1); arr_update(s[k],1,sz,y,1); k+=lowbit(k); } } int query(int last,int now,int l,int r,int x){ if(l==r) return l; int cnt=sum[ls[now]]-sum[ls[last]]; for(int i=1;i<=cntl;++i) cnt-=sum[ls[rootl[i]]]; for(int i=1;i<=cntr;++i) cnt+=sum[ls[rootr[i]]]; int mid=l+r>>1; if(cnt>=x){ for(int i=1;i<=cntl;++i) rootl[i]=ls[rootl[i]]; for(int i=1;i<=cntr;++i) rootr[i]=ls[rootr[i]]; return query(ls[last],ls[now],l,mid,x); }else{ for(int i=1;i<=cntl;++i) rootl[i]=rs[rootl[i]]; for(int i=1;i<=cntr;++i) rootr[i]=rs[rootr[i]]; return query(rs[last],rs[now],mid+1,r,x-cnt); } } int kth(int l,int r,int k){ cntl=cntr=0; for(int i=l-1;i;i-=lowbit(i)) rootl[++cntl]=s[i]; for(int i=r;i;i-=lowbit(i)) rootr[++cntr]=s[i]; return b[query(rt[l-1],rt[r],1,sz,k)]; } }ac; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%d",&a[i]),b[++sz]=a[i]; for(int i=1;i<=m;++i){ char c;scanf(" %c",&c); if(c=='Q') scanf("%d%d%d",&q[i].i,&q[i].j,&q[i].k),q[i].opt=1; else scanf("%d%d",&q[i].i,&q[i].j),b[++sz]=q[i].j; } sort(b+1,b+sz+1); int num=unique(b+1,b+sz+1)-b-1; sz=num; for(int i=1;i<=n;++i) ac.update(rt[i-1],rt[i],1,sz,get(a[i])); for(int i=1;i<=m;++i){ if(q[i].opt) printf("%d\n",ac.kth(q[i].i,q[i].j,q[i].k)); else ac.arr_update(q[i].i,q[i].j); } return 0; }