ZOJ2112 Dynamic Rank(可持久化线段树套树状数组)

人生第一道树套树的题,看着bin巨的代码才学会,太累了,文字明天补

#include<bits/stdc++.h>

using namespace std;
const int maxn=60010;
int n,q,m,tot;
int a[maxn];
int t[maxn];
int T[maxn];
int lson[maxn*40];
int rson[maxn*40];
int c[maxn*40];
int S[maxn];

struct Query {
    int Kind;
    int l,r,k;
}query[maxn];

void Init_hash (int k) {
    sort(t,t+k);
    m=unique(t,t+k)-t;
}
int Hash (int x) {
    return lower_bound(t,t+m,x)-t;
}
int build (int l,int r) {
    int root=tot++;
    c[root]=0;
    if (l!=r) {
        int mid=(l+r)>>1;
        lson[root]=build(l,mid);
        rson[root]=build(mid+1,r);
    }
    return root;
}

int Insert (int root,int pos,int val) {
    int newRoot=tot++;
    int tmp=newRoot;
    int l=0;
    int r=m-1;
    c[newRoot]=c[root]+val;
    while (l<r) {
        int mid=(l+r)>>1;
        if (pos<=mid) {
            lson[newRoot]=tot++;
            rson[newRoot]=rson[root];
            newRoot=lson[newRoot];
            root=lson[root];
            r=mid;
        }
        else {
            rson[newRoot]=tot++;
            lson[newRoot]=lson[root];
            newRoot=rson[newRoot];
            root=rson[root];
            l=mid+1;
        }
        c[newRoot]=c[root]+val;
    }
    return tmp;
}




//树状数组部分
int lowbit (int x) {
    return x&-x;
}
int bit[maxn];
void add (int x,int pos,int val) {
    for (int i=x;i<=n;i+=lowbit(i)) S[i]=Insert(S[i],pos,val);
}
int getsum (int x) {
    int ans=0;
    for (int i=x;i;i-=lowbit(i)) ans+=c[lson[bit[i]]];
    return ans;
}

int Query (int left,int right,int k) {
    int left_root=T[left-1];
    int right_root=T[right];
    int l=0;
    int r=m-1;
    for (int i=left-1;i;i-=lowbit(i)) bit[i]=S[i];
    for (int i=right;i;i-=lowbit(i)) bit[i]=S[i];
    while (l<r) {
        int mid=(l+r)>>1;
        int tmp=getsum(right)-getsum(left-1)+c[lson[right_root]]-c[lson[left_root]];
        if (tmp>=k) {
            r=mid;
            for (int i=left-1;i;i-=lowbit(i)) bit[i]=lson[bit[i]];
            for (int i=right;i;i-=lowbit(i)) bit[i]=lson[bit[i]];
            left_root=lson[left_root];
            right_root=lson[right_root];
        }
        else {
            l=mid+1;
            k-=tmp;
            for (int i=left-1;i;i-=lowbit(i)) bit[i]=rson[bit[i]];
            for (int i=right;i;i-=lowbit(i)) bit[i]=rson[bit[i]];
            left_root=rson[left_root];
            right_root=rson[right_root];
        }
    }
    return l;
}

void Modify (int x,int p,int d) {
    for (int i=x;i<=n;i+=lowbit(i)) {
        S[i]=Insert(S[i],p,d);
    }
}


int main () {
    int tt;
    scanf("%d",&tt);
    while (tt--) {
        scanf("%d%d",&n,&q);
        tot=0;
        m=0;
        for (int i=1;i<=n;i++) {
            scanf("%d",&a[i]);
            t[m++]=a[i];
        }
        char op[10];
        for (int i=0;i<q;i++) {
            scanf("%s",op);
            if (op[0]=='Q') {
                query[i].Kind=0;
                scanf("%d%d%d",&query[i].l,&query[i].r,&query[i].k);
            }
            else {
                query[i].Kind=1;
                scanf("%d%d",&query[i].l,&query[i].r);
                t[m++]=query[i].r;
            }
        }
        Init_hash(m);
        T[0]=build(0,m-1);
        for (int i=1;i<=n;i++)
            T[i]=Insert(T[i-1],Hash(a[i]),1);
        for (int i=1;i<=n;i++) S[i]=T[0];
        for (int i=0;i<q;i++) {
            if (query[i].Kind==0) {
                printf("%d\n",t[Query(query[i].l,query[i].r,query[i].k)]);
            }
            else {
                Modify(query[i].l,Hash(a[query[i].l]),-1);
                Modify(query[i].l,Hash(query[i].r),1);
                a[query[i].l]=query[i].r;
            }
        }
    }
}

 

posted @ 2020-05-16 23:36  zlc0405  阅读(164)  评论(0编辑  收藏  举报