主席树模板(动态)

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

}

猜你喜欢

转载自www.cnblogs.com/kgxw0430/p/10220584.html