P2617 Dynamic Rankings(带修主席树)

所谓带修主席树,就是用树状数组的方法维护主席树的前缀和

思路

带修主席树的板子

注意数据范围显然要离散化即可

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Node{
    int sz,lson,rson;
}PT[100100*400];
struct Q{
    char c;
    int l,r,x,val;
}opt[100100];
const int MAXV = 1e9+10;
int Nodecnt,lcnt,rcnt,root[100100],n,m,a[100100],num[200100],nx;
int lroot[100100],rroot[100100];
int lowbit(int x){
    return x&(-x);
}
void update(int L,int R,int &o,int c,int x){
    PT[++Nodecnt]=PT[o];
    o=Nodecnt;
    PT[o].sz+=c;
    if(L==R)
        return;
    int mid=(L+R)>>1;
    if(x<=mid)
        update(L,mid,PT[o].lson,c,x);
    else
        update(mid+1,R,PT[o].rson,c,x);
}
int query(int l,int r,int L,int R,int k){
    lcnt=0,rcnt=0;
    for(int i=L-1;i;i-=lowbit(i))
        lroot[++lcnt]=root[i];
    for(int i=R;i;i-=lowbit(i))
        rroot[++rcnt]=root[i];
    while(l<=r){
        if(l==r)
            return l;
        int lch=0,mid=(l+r)>>1;
        for(int i=1;i<=rcnt;i++)
            lch+=PT[PT[rroot[i]].lson].sz;
        for(int i=1;i<=lcnt;i++)
            lch-=PT[PT[lroot[i]].lson].sz;
        if(k>lch){//to right
            for(int i=1;i<=rcnt;i++)
                rroot[i]=PT[rroot[i]].rson;
            for(int i=1;i<=lcnt;i++)
                lroot[i]=PT[lroot[i]].rson;
            k-=lch;
            l=mid+1;
        }
        else{
            for(int i=1;i<=rcnt;i++)
                rroot[i]=PT[rroot[i]].lson;
            for(int i=1;i<=lcnt;i++)
                lroot[i]=PT[lroot[i]].lson;
            r=mid;
        }
    }
}
void set(int pos,int x,int c){//x-c
    while(pos<=n){
        update(1,nx,root[pos],c,x);
        pos+=lowbit(pos);
    }
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        num[++nx]=a[i];
    }
    for(int i=1;i<=m;i++){
        char c=getchar();
        while(c!='Q'&&c!='C')
            c=getchar();
        if(c=='Q'){
            opt[i].c='Q';
            scanf("%d %d %d",&opt[i].l,&opt[i].r,&opt[i].val);
        }
        else{
            opt[i].c='C';
            scanf("%d %d",&opt[i].val,&opt[i].x);
            num[++nx]=opt[i].x;
        }
    }
    sort(num+1,num+nx+1);
    nx=unique(num+1,num+nx+1)-num-1;
    for(int i=1;i<=n;i++)
        a[i]=lower_bound(num+1,num+nx+1,a[i])-num;
    for(int i=1;i<=m;i++)
        if(opt[i].c=='C')
            opt[i].x=lower_bound(num+1,num+nx+1,opt[i].x)-num;
    for(int i=1;i<=n;i++)
        set(i,a[i],1);
    for(int i=1;i<=m;i++){
        if(opt[i].c=='Q'){
            printf("%d\n",num[query(1,nx,opt[i].l,opt[i].r,opt[i].val)]);
        }
        else{
            set(opt[i].val,a[opt[i].val],-1);
            set(opt[i].val,opt[i].x,1);
            a[opt[i].val]=opt[i].x;
        }
    }
    return 0;
}
posted @ 2018-12-11 21:06  dreagonm  阅读(273)  评论(0编辑  收藏  举报