[主席树]ZOJ2112 && BZOJ1901 Dynamic Rankings

来源:互联网 发布:sql 交 并 编辑:程序博客网 时间:2024/06/05 15:35

题意:n个数,q个询问 (n<=50000, q<=10000)

Q x y z 代表询问[x, y]区间里的第z小的数

C x y    代表将(从左往右数)第x个数变成y

转自:http://www.cnblogs.com/Empress/p/4659824.html

#include <bits/stdc++.h>using namespace std;typedef long long LL;#define lson l, m#define rson m+1, rconst int N=60005;int a[N], Hash[N];int T[N], L[N<<5], R[N<<5], sum[N<<5];int S[N];int n, m, tot;struct node{    int l, r, k;    bool Q;}op[10005];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);}int use[N];void add(int x, int pos, int val){    while(x<=n)    {        S[x]=update(S[x], 1, m, pos, val);        x+=lowbit(x);    }}int Sum(int x){    int ret=0;    while(x>0)    {        ret+=sum[L[use[x]]];        x-=lowbit(x);    }    return ret;}int query(int u, int v, int lr, int rr, int l, int r, int k){    if(l>=r)        return l;    int m=(l+r)>>1;    int tmp=Sum(v)-Sum(u)+sum[L[rr]]-sum[L[lr]];    if(tmp>=k)    {        for(int i=u;i;i-=lowbit(i))            use[i]=L[use[i]];        for(int i=v;i;i-=lowbit(i))            use[i]=L[use[i]];        return query(u, v, L[lr], L[rr], lson, k);    }    else    {        for(int i=u;i;i-=lowbit(i))            use[i]=R[use[i]];        for(int i=v;i;i-=lowbit(i))            use[i]=R[use[i]];        return query(u, v, R[lr], R[rr], rson, k-tmp);    }}void modify(int x, int p, int d){    while(x<=n)    {        S[x]=update(S[x], 1, m, p, d);        x+=lowbit(x);    }}int main(){    int t;    scanf("%d", &t);    while(t--)    {        int q;        scanf("%d%d", &n, &q);        tot=0;        m=0;        for(int i=1;i<=n;i++)        {            scanf("%d", &a[i]);            Hash[++m]=a[i];        }        for(int i=0;i<q;i++)        {            char s[10];            scanf("%s", s);            if(s[0]=='Q')            {                scanf("%d%d%d", &op[i].l, &op[i].r, &op[i].k);                op[i].Q=1;            }            else            {                scanf("%d%d", &op[i].l, &op[i].r);                op[i].Q=0;                Hash[++m]=op[i].r;            }        }        sort(Hash+1, Hash+1+m);        int mm=unique(Hash+1, Hash+1+m)-Hash-1;        m=mm;        T[0]=build(1, m);        for(int i=1;i<=n;i++)            T[i]=update(T[i-1], 1, m, lower_bound(Hash+1, Hash+1+m, a[i])-Hash, 1);        for(int i=1;i<=n;i++)            S[i]=T[0];        for(int i=0;i<q;i++)        {            if(op[i].Q)            {                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, m, op[i].k)]);            }            else            {                modify(op[i].l, lower_bound(Hash+1, Hash+1+m, a[op[i].l])-Hash, -1);                modify(op[i].l, lower_bound(Hash+1, Hash+1+m, op[i].r)-Hash, 1);                a[op[i].l]=op[i].r;            }        }    }    return 0;}


阅读全文
0 0