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; } } } }