正解是树状数组套主席树
也就是动态主席树了
树套树的感觉真爽
#include<stdio.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 111111
#define mid ((l+r)>>1)
int t[maxn*20],ls[maxn*20],rs[maxn*20],sum[maxn*20],cnt;
int n,m;
void build(int &rt,int l,int r){
rt=++cnt;
sum[rt]=0;
if(l==r)return ;
build(ls[rt],l,mid);
build(rs[rt],mid+1,r);
}
void ins(int &rt,int past,int l,int r,int pos,int w){
rt=++cnt;
sum[rt]=sum[past]+w;ls[rt]=ls[past];rs[rt]=rs[past];
if(l==r)return ;
if(pos<=mid)ins(ls[rt],ls[past],l,mid,pos,w);
else ins(rs[rt],rs[past],mid+1,r,pos,w);
}
int L[30],R[30],M,N,cc;
char op[maxn][3];
int query(int l,int r,int k){
if(l==r)return l;
int lsum=0,rsum=0;
for(int i=1;i<=N;++i)lsum+=sum[ls[L[i]]];
for(int i=1;i<=M;++i)rsum+=sum[ls[R[i]]];
int del=rsum-lsum;
if(del>=k){
for(int i=1;i<=N;++i)L[i]=ls[L[i]];
for(int j=1;j<=M;++j)R[j]=ls[R[j]];
return query(l,mid,k);
}
else {
for(int i=1;i<=N;++i)L[i]=rs[L[i]];
for(int j=1;j<=M;++j)R[j]=rs[R[j]];
return query(mid+1,r,k-del);
}
}
int ask(int l,int r,int k){
N=M=0;
for(;l;l-=(l&(-l)))L[++N]=t[l];
for(;r;r-=(r&(-r)))R[++M]=t[r];
return query(1,cc,k);
}
void up(int x,int pos,int fl){
for(;x<=n;x+=(x&(-x))){
ins(t[x],t[x],1,cc,pos,fl);
}
}
int real[maxn<<1],fake[maxn<<1],a[maxn],b[maxn],k[maxn];
int main(){
scanf("%d%d",&n,&m);
cnt=cc=0;
for(int i=1;i<=n;++i){
scanf("%d",&real[i]);
fake[++cc]=real[i];
}
for(int i=1;i<=m;++i){
scanf("%s%d%d",op[i],&a[i],&b[i]);
if(op[i][0]=='Q'){
scanf("%d",&k[i]);
}
else{
fake[++cc]=b[i];
}
}
sort(fake+1,fake+1+cc);
cc=(int)(unique(fake+1,fake+1+cc)-fake-1);
build(t[0],1,cc);
for(int i=1;i<=n;++i){
real[i]=(int)(lower_bound(fake+1,fake+1+cc,real[i])-fake);
up(i,real[i],1);
}
for(int i=1;i<=m;++i){
if(op[i][0]=='Q'){
printf("%d\n",fake[ask(a[i]-1,b[i],k[i])]);
}
else{
int pos=(int)(lower_bound(fake+1,fake+1+cc,b[i])-fake);
up(a[i],real[a[i]],-1);
real[a[i]]=pos;
up(a[i],real[a[i]],1);
}
}
return 0;
}