zoj 2112 Dynamic Rankings (动态主席树)

来源:互联网 发布:好的翻译软件 编辑:程序博客网 时间:2024/06/04 19:16
/*Q x y z 代表询问[x, y]区间里的第z小的数C x y    代表将(从左往右数)第x个数变成y*/#include <stdio.h>#include <algorithm>#include <iostream>#include <string.h>using namespace std;# define lson l,m# define rson m+1,r# define N 60010int a[N],Hash[N],T[N],S[N];int tot;int L[N<<5],R[N<<5],sum[N<<5];int use[N];struct node{    int l,r,k;    int flag;};node op[N];int size;int n;int build(int l,int r){    int rt=(++tot);    sum[rt]=0;    if(l<r)    {        int m=(l+r)>>1;        L[rt]=build(lson);        R[rt]=build(rson);    }    return rt;}int update(int pre,int l,int r,int x,int val){    int rt=(++tot);    L[rt]=L[pre];    R[rt]=R[pre];    sum[rt]=sum[pre]+val;    if(l<r)    {        int m=(l+r)>>1;        if(x<=m)            L[rt]=update(L[pre],lson,x,val);        else            R[rt]=update(R[pre],rson,x,val);    }    return rt;}int lowbit(int x){    return x&(-x);}void add(int x,int pos,int val){    while(x<=n)    {        S[x]=update(S[x],1,size,pos,val);        x+=lowbit(x);    }}int getSum(int x){    int ret=0;    while(x>0)    {        ret+=sum[L[use[x]]];        x-=lowbit(x);    }    return ret;}void modify(int x,int p,int val){    while(x<=n)    {        S[x]=update(S[x],1,size,p,val);        x+=lowbit(x);    }}int query(int u,int v,int lr,int rr,int l,int r,int k){    int i;    if(l>=r)        return l;    int m=(l+r)>>1;    int tmp=getSum(v)-getSum(u)+sum[L[rr]]-sum[L[lr]];    if(tmp>=k)    {        for(i=u; i; i-=lowbit(i))            use[i]=L[use[i]];        for(i=v; i; i-=lowbit(i))            use[i]=L[use[i]];        return query(u,v,L[lr],L[rr],lson,k);    }    else    {        for(i=u; i; i-=lowbit(i))            use[i]=R[use[i]];        for(i=v; i; i-=lowbit(i))            use[i]=R[use[i]];        return query(u,v,R[lr],R[rr],rson,k-tmp);    }}int main(){    int t,q,i,j;    while(~scanf("%d",&t))    {        while(t--)        {            tot=0;            scanf("%d%d",&n,&q);            int m=0;            for(i=1; i<=n; i++)            {                scanf("%d",&a[i]);                Hash[m++]=a[i];            }            for(i=1; i<=q; i++)            {                char str[10];                scanf("%s",&str);                if(str[0]=='Q')                {                    scanf("%d%d%d",&op[i].l,&op[i].r,&op[i].k);                    op[i].flag=0;                }                else                {                    scanf("%d%d",&op[i].l,&op[i].r);                    op[i].flag=1;                    Hash[m++]=op[i].r;                }            }            sort(Hash,Hash+m);            size=unique(Hash,Hash+m)-Hash;            T[0]=build(1,size);            for(i=1; i<=n; i++)            {                int x=lower_bound(Hash,Hash+size,a[i])-Hash;                T[i]=update(T[i-1],1,size,x,1);            }            for(i=1; i<=n; i++)                S[i]=T[0];            for(i=1; i<=q; i++)            {                if(op[i].flag)//修改                {                    modify(op[i].l,lower_bound(Hash,Hash+size,a[op[i].l])-Hash,-1);                    modify(op[i].l,lower_bound(Hash,Hash+size,op[i].r)-Hash,1);                    a[op[i].l]=op[i].r;                }                else                {                    for(int j=op[i].l-1; j; j-=lowbit(j))                        use[j]=S[j];                    for(int j=op[i].r; j; j-=lowbit(j))                        use[j]=S[j];                    printf("%d\n",Hash[query(op[i].l-1,op[i].r,T[op[i].l-1],T[op[i].r],1,size,op[i].k)]);                }            }        }    }    return 0;}

0 0
原创粉丝点击