区间第K大数终极版、
虽然好似可以主席树、、但是为了锻炼代码能力写了树套树、
果然代码能力就是不行、
不得不承认很少有人的代码会写得比我丑了、、是该改进下了、
Code:
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
struct point{
int fa,lson,rson;
int data,muti,size;
}node[400010];
char od,te;
const int maxn=40010;
int top=0,minnum=9999999,maxnum=-9999999,n,vv,cnt;
int tree[maxn],l[maxn],r[maxn],a[maxn],lt[maxn],rt[maxn];
int newsplay(int key){
top++;
node[top].size=node[top].muti=1;
node[top].lson=node[top].rson=node[top].fa=0;
node[top].data=key;
return top;
}
void zig(int now){
int tf=node[now].fa,te=node[now].size-node[node[now].lson].size;
if ((node[node[tf].fa].lson)==tf)
node[node[tf].fa].lson=now;
else node[node[tf].fa].rson=now;
node[tf].rson=node[now].lson;
node[now].lson=tf;
node[now].fa=node[tf].fa;node[tf].fa=now;
if (node[tf].rson) node[node[tf].rson].fa=tf;
node[now].size=node[tf].size;
node[tf].size-=te;
}
void zag(int now){
int tf=node[now].fa,te=node[now].size-node[node[now].rson].size;
if ((node[node[tf].fa].lson)==tf)
node[node[tf].fa].lson=now;
else node[node[tf].fa].rson=now;
node[tf].lson=node[now].rson;
node[now].rson=tf;
node[now].fa=node[tf].fa;node[tf].fa=now;
if (node[tf].lson) node[node[tf].lson].fa=tf;
node[now].size=node[tf].size;
node[tf].size-=te;
}
void splay(int root,int now){
if (root==now || node[now].fa==root) return ;
while (root!=node[now].fa){
if (node[node[now].fa].fa==root){
if (node[node[now].fa].lson==now) zag(now);else zig(now);
return ;
}
if (node[node[node[now].fa].fa].lson==node[now].fa)
if (node[node[now].fa].lson==now){zag(now);zag(now);}
else {zig(now);zag(now);}
else
if (node[node[now].fa].lson==now){zag(now);zig(now);}
else {zig(now);zig(now);}
}
}
void insert(int now,int key){
int x=now;
while (1){
node[x].size++;
if (node[x].data==key){
node[x].muti++;
splay(now,x);
return ;
}
if (node[x].data>key){
if (!node[x].lson){
node[x].lson=newsplay(key);
node[node[x].lson].fa=x;
splay(now,node[x].lson);
return ;
}else x=node[x].lson;
}
else
if (!node[x].rson){
node[x].rson=newsplay(key);
node[node[x].rson].fa=x;
splay(now,node[x].rson);
return ;
}else x=node[x].rson;
}
}
void deldata(int now,int key){
int x=now;
while (1){
node[x].size--;
if (node[x].data==key){
node[x].muti--;
return ;
}
if (node[x].data>key) x=node[x].lson;
else x=node[x].rson;
}
}
int count(int now,int key){
int res=0,x=now;
while (x){
if (node[x].data==key){
res+=node[x].size-node[node[x].rson].size;
splay(now,x);
return res;
}
if (node[x].data>key) x=node[x].lson;
else{
res+=node[x].size-node[node[x].rson].size;
x=node[x].rson;
}
}
return res;
}
void build(int now,int lm,int rm){
tree[now]=newsplay(a[lm]);
l[now]=lm;r[now]=rm;
if (lm==rm){
lt[now]=rt[now]=0;
return ;
}
for (int i=lm+1;i<=rm;i++){
insert(tree[now],a[i]);
}
build(now*2,lm,(lm+rm)/2);
build(now*2+1,(lm+rm)/2+1,rm);
lt[now]=now*2;rt[now]=now*2+1;
}
void query(int now,int lm,int rm,int key){
if (l[now]>rm || r[now]<lm) return ;
if (l[now]>=lm && r[now]<=rm){
cnt+=count(tree[now],key);
return ;
}
if (lt[now]) query(lt[now],lm,rm,key);
if (rt[now]) query(rt[now],lm,rm,key);
return ;
}
void change(int now,int tar,int ori,int key){
if (l[now]>tar || r[now]<tar) return ;
deldata(tree[now],ori);
insert(tree[now],key);
if (l[now]!=r[now]){
change(lt[now],tar,ori,key);
change(rt[now],tar,ori,key);
}
return ;
}
void scan(int &x){
te=getchar();
while (te<'0' || te>'9') te=getchar();
x=te-'0';te=getchar();
while (te>='0' && te<='9'){
x=x*10+te-'0';
te=getchar();
}
}
int main(){
scanf("%d%d",&n,&vv);
for (int i=1;i<=n;i++){
int cl;scan(cl);a[i]=cl;
minnum=min(minnum,a[i]);
maxnum=max(maxnum,a[i]);
}
scanf("\n");
build(1,1,n);
while (vv--){
int cl,cr,th;
od=getchar();
if (od=='Q'){
scan(cl);scan(cr);scan(th);
int ll=minnum,rr=maxnum;
while (ll<rr){
cnt=0;
query(1,cl,cr,(ll+rr)/2);
if (cnt>=th) rr=(ll+rr)/2;
else ll=(ll+rr)/2+1;
}
printf("%d\n",ll);
}
else{
scan(cl);scan(cr);
minnum=min(minnum,cr);
maxnum=max(maxnum,cr);
change(1,cl,a[cl],cr);
a[cl]=cr;
}
}
return 0;
}