闲来无事,水水主席树。发现只要求第8大,用什么?对了,用线段树+优先队列。时间复杂度一算,没问题。开完O2后提交,额,AC了。
#include<bits/stdc++.h>
#define pq priority_queue<int,vector<int>,greater<int> >
#define N 100010
using namespace std;
int n,m;
pq tree[N<<2];
void push_up(int rt){
while(!tree[rt].empty()) tree[rt].pop();
pq t=tree[rt<<1];
while(!t.empty()){
tree[rt].push(t.top());
t.pop();
}
t=tree[rt<<1|1];
while(!t.empty()){
tree[rt].push(t.top());
t.pop();
}
while(tree[rt].size()>8) tree[rt].pop();
}
void update(int l,int r,int rt,int a,int b){
if(l==r){
if(!tree[rt].empty()) tree[rt].pop();
tree[rt].push(b);
return;
}
int mid=l+r>>1;
if(a<=mid) update(l,mid,rt<<1,a,b);
else update(mid+1,r,rt<<1|1,a,b);
push_up(rt);
}
pq query(int l,int r,int rt,int a,int b){
if(a<=l&&b>=r) return tree[rt];
int mid=l+r>>1;
pq ans,t;
if(a<=mid){
t=query(l,mid,rt<<1,a,b);
while(!t.empty()){
ans.push(t.top());
t.pop();
}
}
if(b>mid){
t=query(mid+1,r,rt<<1|1,a,b);
while(!t.empty()){
ans.push(t.top());
t.pop();
}
}
while(ans.size()>8) ans.pop();
return ans;
}
int main(){
scanf("%d%d",&n,&m);
while(m--){
char c[1];
scanf("%s",c);
if(c[0]=='C'){
int p,x;
scanf("%d%d",&p,&x);
update(1,n,1,p,x);
}else{
int a,b;
scanf("%d%d",&a,&b);
pq ans=query(1,n,1,a,b);
if(ans.size()<8) printf("0\n");
else printf("%d\n",ans.top());
}
}
return 0;
}