犯了很多SB的错误。。
数据规模是 50000, 那么一个块大概230。
做法是块状思想, 二分答案计算它的 rank是否满足,满足则输出这个答案
时间复杂度 n*sqrt(n)*logn 十秒的时限妥妥的AC。。
//tpl
//ipqhjjybj_tpl.h
//header.h
#include <cstdio>
#include <cstdlib>
#include <map>
#include <set>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <sstream>
#include <math.h>
#define mp(x,y) make_pair(x,y)
#define pii pair<int,int>
#define pLL pair<long long ,long long>
#define pb(x) push_back(x)
#define rep(i,j,k) for(int i = j; i < k;i++)
#define MAX(x,a) x=((x)<(a))?(a):(x);
#define MIN(x,a) x=((x)>(a))?(a):(x);
using namespace std;
const int N = 55555;
const int Sqrt = 240;
int n,m;
int a[N];
char s[10];
vector<int> vec[444];
vector<int> h[444];
vector<int> fh;
int maxK;
void modify(int l,int val){
int k1 = l/Sqrt ,l1 = l%Sqrt;
int tmp = vec[k1][l1];
if(tmp == val) return;
vec[k1][l1] = val;
int pos = lower_bound(h[k1].begin(),h[k1].end(),tmp) - h[k1].begin();
int sz = h[k1].size();
l1 = pos;
h[k1][pos] = val;
if(val > tmp){
while( l1 + 1 < sz && h[k1][l1] > h[k1][l1+1])
swap(h[k1][l1], h[k1][l1+1]) , l1++;
}else{
while( l1 > 0 && h[k1][l1] < h[k1][l1-1]){
swap(h[k1][l1], h[k1][l1-1]),l1--;
}
}
}
// 返回 [l,r] 区间内小于 val 的数的数目
// 并且 统计 = val 的数目 存于 exis
int query(int l,int r,int val,int &exis){
int k1 = l/Sqrt , l1 = l % Sqrt , k2 = r/Sqrt , l2 = r%Sqrt;
int ret = 0; exis = 0;
l2++;
if(k1 == k2){
rep(i,l1,l2)
if(vec[k1][i] < val){
ret++;
}
else if(vec[k1][i] == val)
exis++;
}else{
rep(i,k1+1,k2){
int pos = lower_bound(h[i].begin(),h[i].end(),val) - h[i].begin();
int kk = upper_bound(h[i].begin(),h[i].end(), val) - h[i].begin();
pos = min(pos,(int)h[i].size());
kk = min(kk,(int)h[i].size());
if(pos!=h[i].size() && h[i][pos] == val)
exis += kk - pos;
ret += pos ;
}
int sz = vec[k1].size();
rep(i,l1,sz)
if(vec[k1][i] < val){
ret++;
}
else if(vec[k1][i] == val)
exis++;
rep(i,0,l2)
if(vec[k2][i] < val){
ret++;
}
else if(vec[k2][i] == val)
exis++;
}
return ret;
}
int solve(int ql,int qr,int k){
int l = 0,r = fh.size()-1 , ans=-1;
int exis;
while(l <= r){
int m = (l+r)>>1;
int mid_val = fh[m];
int ret = query(ql,qr,mid_val,exis);
if( ret < k && ret+exis >= k){
ans = mid_val; break;
}else if(ret < k){
l = m + 1;
}else{
r = m - 1;
}
}
return ans;
}
struct ed{
int l,r,k;
char c;
void input(){
scanf("%s %d %d",s,&l,&r);
l--;
if((c = s[0]) == 'Q'){
r--;
scanf("%d",&k);
}
}
}E[N<<1];
int main(){
int tt;
scanf("%d",&tt);
while(tt--){
scanf("%d %d",&n,&m);
maxK = n/Sqrt+4;
rep(i,0,maxK)
vec[i].clear(),h[i].clear();
rep(i,0,n) scanf("%d",a+i);
rep(i,0,n){
vec[i/Sqrt].pb(a[i]),h[i/Sqrt].pb(a[i]);
}
rep(i,0,maxK) sort(h[i].begin(),h[i].end());
rep(i,0,m) E[i].input();
fh.clear();
rep(i,0,m) if(E[i].c=='C') fh.pb(E[i].r);
rep(i,0,n) fh.pb(a[i]);
sort(fh.begin(),fh.end());
fh.erase(unique(fh.begin(),fh.end()),fh.end());
rep(i,0,m){
int l = E[i].l,r = E[i].r;
char c = E[i].c ;
if(c == 'Q'){
int k = E[i].k;
printf("%d\n",solve(l,r,k));
}else{
modify(l,r);
}
}
}
return 0;
}