ZOJ 2112 Dynamic Rankings 线段树套平衡树

------------

const int N=60010;
const int M=10010;

class SegmentTree_Treap{
private:
    struct Treap{
        int key,fix,cnt,size,ch[2];
    }T[N*15];
    int tree[N<<1],nodecnt;
    int ID(int l,int r){return (l+r)|(l!=r);}
    void update(int x){
        T[x].size=T[T[x].ch[0]].size+T[T[x].ch[1]].size+T[x].cnt;
    }
    void rotate(int &x,int t){
        int y=T[x].ch[t];
        T[x].ch[t]=T[y].ch[!t];
        T[y].ch[!t]=x;
        update(x);
        update(y);
        x=y;
    }
    void insert(int &x,int t){
        if (!x){
            x=++nodecnt;
            T[x].key=t;
            T[x].fix=rand();
            T[x].cnt=1;
            T[x].ch[0]=T[x].ch[1]=0;
        }
        else if (T[x].key==t) T[x].cnt++;
        else{
            int k=T[x].key<t;
            insert(T[x].ch[k],t);
            if (T[x].fix<T[T[x].ch[k]].fix) rotate(x,k);
        }
        update(x);
    }
    void erase(int &x,int t){
        if (T[x].key==t){
            if (T[x].cnt==1){
                if (!T[x].ch[0]&&!T[x].ch[1]){
                    x=0;
                    return;
                }
                rotate(x,T[T[x].ch[0]].fix<T[T[x].ch[1]].fix);
                erase(x,t);
            }
            else T[x].cnt--;
        }
        else erase(T[x].ch[T[x].key<t],t);
        update(x);
    }
    int select(int x,int t){
        if (!x) return 0;
        if (T[x].key>t) return select(T[x].ch[0],t);
        return T[x].cnt+T[T[x].ch[0]].size+select(T[x].ch[1],t);
    }
public:
    void treeins(int l,int r,int i,int x){
        insert(tree[ID(l,r)],x);
        if (l==r) return;
        int m=(l+r)>>1;
        if (i<=m) treeins(l,m,i,x);
        else treeins(m+1,r,i,x);
    }
    void treedel(int l,int r,int i,int x){
        erase(tree[ID(l,r)],x);
        if (l==r) return;
        int m=(l+r)>>1;
        if (i<=m) treedel(l,m,i,x);
        else treedel(m+1,r,i,x);
    }
    int query(int l,int r,int x,int y,int t){
        if (l==r) return l;
        int m=(l+r)>>1;
        int ans=select(tree[ID(l,m)],y)-select(tree[ID(l,m)],x);
        if (ans>=t) return query(l,m,x,y,t);
        return query(m+1,r,x,y,t-ans);
    }
    void init(){
        T[0].size=0;
        T[0].fix=-INF;
        nodecnt=0;
    }
    void clearTree(){
        memset(tree,0,sizeof(tree));
    }
}tr;
char ctrl[M][3];
int cnt,n,m;
int P[M],Q[M],a[N],b[N],K[M];
int main(){
    int T;
    scanf("%d",&T);
    while (T--){
        scanf("%d%d",&n,&m);
        tr.clearTree();
        tr.init();
        cnt=0;
        for (int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            b[++cnt]=a[i];
        }
        for (int i=1;i<=m;i++){
            scanf("%s%d%d",ctrl[i],&P[i],&Q[i]);
            if (ctrl[i][0]=='Q') scanf("%d",&K[i]);
            else b[++cnt]=Q[i];
        }
        sort(b+1,b+1+cnt);
        cnt=unique(b+1,b+1+cnt)-b-1;
        for (int i=1;i<=n;i++){
            a[i]=lower_bound(b+1,b+1+cnt,a[i])-b;
            tr.treeins(1,cnt,a[i],i);
        }
        for (int i=1;i<=m;i++){
            if (ctrl[i][0]=='Q'){
                int id=tr.query(1,cnt,P[i]-1,Q[i],K[i]);
                printf("%d\n",b[id]);
            }
            else{
                tr.treedel(1,cnt,a[P[i]],P[i]);
                a[P[i]]=lower_bound(b+1,b+1+cnt,Q[i])-b;
                tr.treeins(1,cnt,a[P[i]],P[i]);
            }
        }
    }
	return 0;
}


------------

你可能感兴趣的:(ZOJ 2112 Dynamic Rankings 线段树套平衡树)