[BZOJ1901]Dynamic Rankings
Description
给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1
],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改
变后的a继续回答上面的问题。
Input
第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000)。
分别表示序列的长度和指令的个数。
第二行有n个数,表示a[1],a[2]……a[n],这些数都小于10^9。
接下来的m行描述每条指令
每行的格式是下面两种格式中的一种。
Q i j k 或者 C i t
Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)
表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。
C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t
m,n≤10000
Output
对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。
Sample Input
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
Sample Output
3
6
6
第一次写树状数组套主席树,还是很好写的,思路也非常好理解
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define M 20010 6 #define ls L[node] 7 #define rs R[node] 8 using namespace std; 9 int n,m,sz,cnt,tx,ty; 10 int a[M<<3],b[M<<3],px[M<<3],py[M<<3],ql[M<<3],qr[M<<3],qk[M<<3]; 11 int rt[M<<3],val[M<<9],L[M<<9],R[M<<9]; 12 void insert(int &node,int l,int r,int x,int v) { 13 if(!node) node=++sz;val[node]+=v; 14 if(l==r) return; 15 int mid=(l+r)/2; 16 if(x<=mid) insert(ls,l,mid,x,v); 17 else insert(rs,mid+1,r,x,v); 18 } 19 void add(int loc,int v) { 20 int p=lower_bound(b+1,b+1+cnt,a[loc])-b; 21 for(int i=loc;i<=n;i+=(i&-i)) 22 insert(rt[i],1,cnt,p,v); 23 } 24 int query(int l,int r,int k) { 25 if(l==r) return l; 26 int sum=0,mid=(l+r)/2; 27 for(int i=1;i<=tx;i++) sum-=val[L[px[i]]]; 28 for(int i=1;i<=ty;i++) sum+=val[L[py[i]]]; 29 if(k<=sum) { 30 for(int i=1;i<=tx;i++) px[i]=L[px[i]]; 31 for(int i=1;i<=ty;i++) py[i]=L[py[i]]; 32 return query(l,mid,k); 33 } 34 else { 35 k-=sum; 36 for(int i=1;i<=tx;i++) px[i]=R[px[i]]; 37 for(int i=1;i<=ty;i++) py[i]=R[py[i]]; 38 return query(mid+1,r,k); 39 } 40 } 41 int main() { 42 scanf("%d%d",&n,&m);cnt=n; 43 for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i]; 44 for(int i=1;i<=m;i++) { 45 char s[10];scanf("%s",s); 46 scanf("%d%d",&ql[i],&qr[i]); 47 if(s[0]=='Q') scanf("%d",&qk[i]); 48 else b[++cnt]=qr[i]; 49 } 50 sort(b+1,b+1+cnt); 51 cnt=unique(b+1,b+1+cnt)-b-1; 52 for(int i=1;i<=n;i++) add(i,1); 53 for(int i=1;i<=m;i++) { 54 if(qk[i]) { 55 tx=ty=0; 56 for(int j=ql[i]-1;j;j-=(j&-j)) px[++tx]=rt[j]; 57 for(int j=qr[i];j;j-=(j&-j)) py[++ty]=rt[j]; 58 printf("%d\n",b[query(1,cnt,qk[i])]); 59 } 60 else { 61 add(ql[i],-1); 62 a[ql[i]]=qr[i]; 63 add(ql[i],1); 64 } 65 } 66 return 0; 67 }