# bzoj 1901 动态求k大值

#### 树状数组 + 主席树 V5 无限Orz啊

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define lowbit(i) (i&-i)
using namespace std;
const int M = 50050;
struct node {
int l,r,cnt;
}tree[M*46];
int root[M];
int top;
int build(int l,int r) {
int k = ++top;
int mid=(l+r) >> 1;
if(l==r) return k;
tree[k].l = build(l,mid);
tree[k].r = build(mid+1,r);
return k;
}
int insertInto(int rt,int pos,int l,int r,int c) {
int k = ++ top;
tree[k] = tree[rt];
tree[k].cnt = tree[rt].cnt + c;
if(l==r) return k;
int mid=(l+r) >>  1;
if(pos<=mid) tree[k].l = insertInto(tree[rt].l,pos,l,mid,c);
else tree[k].r = insertInto(tree[rt].r,pos,mid+1,r,c);
return k;
}
int n;
int lisan[M*2],qu[M][4],a[M],len;
int Hash(int val) {
return lower_bound(lisan,lisan+len,val) - lisan + 1;
}
void update(int l,int pos,int c) {
for(int i= l;i<=n;i += lowbit(i)) {
root[i] = insertInto(root[i],pos,1,len,c);
}
}
int Qr[33],Ql[44],cntr,cntl;
int quy(int l,int r,int pos)  {
if(l==r) return l;
int c = 0;
for(int i=0;i<cntr;i++ ) c += tree[tree[Qr[i]].l].cnt;
for(int i=0;i<cntl;i++ ) c -= tree[tree[Ql[i]].l].cnt;
int mid = (l+r) >>1;
if(c<pos) {
for(int i=0;i<cntr;i++) Qr[i] = tree[Qr[i]].r;
for(int i=0;i<cntl;i++) Ql[i] = tree[Ql[i]].r;
return quy(mid+1,r,pos-c);
} else   {
for(int i=0;i<cntr;i++) Qr[i] = tree[Qr[i]].l;
for(int i=0;i<cntl;i++) Ql[i] = tree[Ql[i]].l;
return quy(l,mid,pos);
}
}
int query(int l,int r,int k)  {
cntr = cntl = 0;
for(int i=r;i;  i -= lowbit(i)) Qr[cntr++] = root[i];
for(int i=l-1;i;i -= lowbit(i)) Ql[cntl++] = root[i];
return quy(1,len,k);
}
int main(){
int m;
while(cin>>n>>m){
len = 0 ,top =0;
for(int i=1;i<=n;i++)  {
scanf("%d",&a[i]);
lisan[len ++] = a[i];
}
char st[4];
int l,r,k;
for(int i=0;i<m;i++)  {
scanf("%s%d%d",st,&l,&r);
if(st[0]=='Q') {
qu[i][0]=1;
qu[i][1]=l;
qu[i][2]=r;
scanf("%d",&k);
qu[i][3]=k;
}
else {
qu[i][0]=-1;
qu[i][1]=l;
qu[i][2]=r;
lisan[len++]=r;
}
}
sort(lisan,lisan+len);
len = unique(lisan,lisan+len)-lisan;
root[0] = build(1,len);
for(int i=1;i<=n;i++) root[i] = root[0];
for(int i=1;i<=n;i++) update(i,Hash(a[i]),1);
for(int i=0;i<m;i++)  {
if(qu[i][0] == 1) {
printf("%d\n" ,lisan [ query(qu[i][1],qu[i][2],qu[i][3]) -1 ]);
} else  {
int pos = Hash(a[qu[i][1]]);
int pos1 = Hash(qu[i][2]);
a[qu[i][1]] = qu[i][2];
update(qu[i][1],pos,-1);
update(qu[i][1],pos1,1);
}
}
}
return 0;
}


©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客