参考:
http://blog.csdn.net/acm_cxlove/article/details/8565309
http://www.cnblogs.com/Rlemon/archive/2013/05/24/3096264.html
http://www.cnblogs.com/kuangbin/p/3308118.html
http://seter.is-programmer.com/posts/31907.html
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <vector> #include <algorithm> #define lowbit(x) (x&(-x)) using namespace std; const int N = 60005; const int M = N * 40;//前几次用了30倍 WA了几发 const int MM = 10005; int n,m,q,tot; int a[N],t[N]; int T[N],ls[M],rs[M],c[M],use[N],s[N]; struct Question{ int kind, l, r, k; }que[MM]; void Init_hash(){ sort(t+1,t+m+1); m = unique(t+1,t+1+m)-t-1; } int hash(int x){ return lower_bound(t+1,t+1+m,x)-t; } void build(int l, int r, int &rt){ rt = tot ++; c[rt] = 0; if(l != r){ int mid = (l+r)>>1; build(l, mid, ls[rt] ); build(mid+1, r, rs[rt]); } } int update(int root, int pos, int val){ int newroot = tot++, tmp = newroot; c[newroot] = c[root] + val; int l = 1, r = m; while(l < r){ int mid = (l+r)>>1; if(pos <= mid){ ls[newroot] = tot++; rs[newroot] = rs[root]; newroot = ls[newroot]; root = ls[root]; r = mid; } else { rs[newroot] = tot++; ls[newroot] = ls[root]; newroot = rs[newroot]; root = rs[root]; l = mid+1; } c[newroot] = c[root] + val; } return tmp; } void Modify(int x, int pos, int val){ while(x<=n){ s[x] = update(s[x],pos,val); x += lowbit(x); } } int sum(int x){ int ret = 0; while(x>0){ ret += c[ls[use[x]]]; x -= lowbit(x); } return ret; } int query(int left, int right, int k){ int left_root = T[left-1], right_root = T[right]; int l = 1, r = m; for(int i = left-1; i; i -= lowbit(i))use[i] = s[i]; for(int i = right; i; i -= lowbit(i))use[i] = s[i]; while(l < r){ int mid = (l+r)>>1; int cot = sum(right) - sum(left-1) + c[ls[right_root]] - c[ls[left_root]]; if(cot >= k){ r = mid; left_root = ls[left_root]; right_root = ls[right_root]; for(int i = left-1; i; i -= lowbit(i))use[i] = ls[use[i]]; for(int i = right; i; i -= lowbit(i))use[i] = ls[use[i]]; } else { l = mid+1; k -= cot; left_root = rs[left_root]; right_root = rs[right_root]; for(int i = left-1; i; i -= lowbit(i))use[i] = rs[use[i]]; for(int i = right; i; i -= lowbit(i))use[i] = rs[use[i]]; } } return l; } int main(){ char str[5]; int l,r,k,ks; //freopen("in.txt","r",stdin); scanf("%d",&ks); while(ks--){ scanf("%d%d",&n, &q); tot = m = 0; for(int i = 1; i <= n; i++ ){ scanf("%d", a+i); t[++m] = a[i]; } for(int i = 0; i < q; i++){ scanf("%s",str); if(str[0] == 'Q'){ scanf("%d%d%d", &l, &r, &k); que[i] = Question{0, l, r, k}; } else { scanf("%d%d", &l, &k); que[i] = Question{1, l, 0, k}; t[++m] = k; } } Init_hash(); build(1,m,T[0]); for(int i = 1; i <= n; i++){ T[i] = update(T[i-1], hash(a[i]), 1); s[i] = T[0]; } for(int i = 0; i < q; i++){ if(que[i].kind == 0){ printf("%d\n",t[query(que[i].l,que[i].r,que[i].k)]); } else { Modify(que[i].l,hash(a[que[i].l]),-1); Modify(que[i].l,hash(que[i].k),1); a[que[i].l] = que[i].k; } } } return 0; }