主席树模板(支持修改)

#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;
}

猜你喜欢

转载自blog.csdn.net/qq_39759315/article/details/85473713