题目描述
给定一个含有 (n) 个数的序列 (a_1,a_2 dots a_n),需要支持两种操作:
Q l r k 表示查询下标在区间 ([l,r]) 中的第 (k) 小的数
C x y 表示将 (a_x) 改为 (y)
输入格式
第一行两个正整数 (n,m),表示序列长度与操作个数。
第二行 (n) 个整数,表示 (a_1,a_2 dots a_n)。
接下来 (m) 行,每行表示一个操作,都为上述两种中的一个。
输出格式
对于每一次询问,输出一行一个整数表示答案。
离散化莫名出锅
#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=2e5+5;
inline int read(){
int x=0; char c=getchar();
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();}
return x;
}
#define mid ((l+r)>>1)
int a[N],n,m,len;
int T[N*600],ls[N*600],rs[N*600],val[N*600],cnt;
void update(int &p,int l,int r,int pos,int d){
if(!p)p=++cnt;
if(l==r){ val[p]+=d; return; }
if(pos<=mid)update(ls[p],l,mid,pos,d);
else update(rs[p],mid+1,r,pos,d);
val[p]=val[ls[p]]+val[rs[p]];
}
void add(int x,int y){
for(;x<=n;x+=x&(-x))update(T[x],1,len,y,1);
}
void del(int x,int y){
for(;x<=n;x+=x&(-x))update(T[x],1,len,y,-1);
}
struct QU{
int opt,l,r,k;
}e[N];
int b[N],top;
struct node{
vector<int>A,B;
inline int sum(){
int x=0;
for(int i=0;i<A.size();i++)x+=val[ls[A[i]]];
for(int i=0;i<B.size();i++)x-=val[ls[B[i]]];
return x;
}
inline void changel(){
for(int i=0;i<A.size();i++)A[i]=ls[A[i]];
for(int i=0;i<B.size();i++)B[i]=ls[B[i]];
}
inline void changer(){
for(int i=0;i<A.size();i++)A[i]=rs[A[i]];
for(int i=0;i<B.size();i++)B[i]=rs[B[i]];
}
};
vector<int> sum(int x){
vector<int>Q; Q.clear();
for(;x;x-=x&(-x))Q.push_back(T[x]);
return Q;
}
int query(node p,int l,int r,int k){
if(l==r)return l;
int x=p.sum();
if(k<=x){
p.changel();
return query(p,l,mid,k);
}else{
p.changer();
return query(p,mid+1,r,k-x);
}
}
signed main(){
n=read(),m=read();
for(int i=1;i<=n;i++)b[i]=a[i]=read(); top=n;
char ch[4];
for(int i=1;i<=m;i++){
scanf("%s",ch);
if(ch[0]=='Q')e[i].l=read(),e[i].r=read(),e[i].k=read(),e[i].opt=1;
else e[i].l=read(),e[i].r=read(),b[++top]=e[i].r;
}
sort(b+1,b+1+top);
len=top;
for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+len+1,a[i])-b;
for(int i=1;i<=n;i++)add(i,a[i]);
for(int i=1;i<=m;i++){
int opt=e[i].opt,l=e[i].l,r=e[i].r,k=e[i].k;
if(opt==1){
node t=(node){sum(r),sum(l-1)};
printf("%d
",b[query(t,1,len,k)]);
}else{
r=lower_bound(b+1,b+1+top,r)-b;
del(l,a[l]);
add(l,r);
a[l]=r;
}
}
}