参考:
http://blog.youkuaiyun.com/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;
}