给出一个数列,要求支持区间查询第K小和单点修改。
因为不强制在线,先将修改操作和原数列一起离散化
建树方式更改为使用树状数组维护前缀和,主席树只记录这一个位置的
修改时要在
查询时同时累加
最后在树上二分计算答案
时空复杂度都是
/**************************************************************
Problem: 1901
User: bdzxt
Language: C++
Result: Accepted
Time:380 ms
Memory:32716 kb
****************************************************************/
#include<bits/stdc++.h>
#define LL long long
#define clr(x,i) memset(x,i,sizeof(x))
using namespace std;
const int N=10005;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
#define lowbit(x) (x&(-x))
struct Node{
int l,r,sz;
}t[N*265];
int n,m,a[N],rt[N*2],tot,rk[N*2],sz;
int L[33],R[33],cntl,cntr;
int qf[N],qx[N],qy[N],qz[N];
void upd(int l,int r,int &x,int y,int p,int flag)
{
x=++tot;t[x]=t[y];t[x].sz+=flag;
if(l==r)return;
int mid=(l+r)>>1;
if(p<=mid)
upd(l,mid,t[x].l,t[y].l,p,flag);
else
upd(mid+1,r,t[x].r,t[y].r,p,flag);
}
int query(int l,int r,int k)
{
if(l==r)return l;
int suml=0,sumr=0,mid=(l+r)>>1;
for(int i=1;i<=cntl;i++)suml+=t[t[L[i]].l].sz;
for(int i=1;i<=cntr;i++)sumr+=t[t[R[i]].l].sz;
if(k<=(sumr-suml)){
for(int i=1;i<=cntl;i++)L[i]=t[L[i]].l;
for(int i=1;i<=cntr;i++)R[i]=t[R[i]].l;
return query(l,mid,k);
}
else{
for(int i=1;i<=cntl;i++)L[i]=t[L[i]].r;
for(int i=1;i<=cntr;i++)R[i]=t[R[i]].r;
return query(mid+1,r,k-(sumr-suml));
}
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++) a[i]=rk[++sz]=read();
char op[3];int x,y,z;
for(int i=1;i<=m;i++)
{
scanf("%s",op);
qx[i]=read();qy[i]=read();
if(op[0]=='Q') qz[i]=read();
else rk[++sz]=qy[i],qf[i]=1;
}
sort(rk+1,rk+sz+1);
sz=unique(rk+1,rk+sz+1)-rk-1;
for(int i=1;i<=n;i++)
{
int v=lower_bound(rk+1,rk+sz+1,a[i])-rk;
for(int j=i; j<=n; j+=lowbit(j))
upd(1,sz,rt[j],rt[j],v,1);
}
for(int i=1;i<=m;i++)
{
if(qf[i]==0){
int v=lower_bound(rk+1,rk+sz+1,qz[i])-rk;
cntl=cntr=0;
for(int j=qx[i]-1; j>0; j-=lowbit(j))
L[++cntl]=rt[j];//
for(int j=qy[i]; j>0; j-=lowbit(j))
R[++cntr]=rt[j];//
int ans=rk[query(1,sz,qz[i])];
printf("%d\n",ans);
}
else{
int v=lower_bound(rk+1,rk+sz+1,a[qx[i]])-rk;
for(int j=qx[i]; j<=n; j+=lowbit(j))
upd(1,sz,rt[j],rt[j],v,-1);
a[qx[i]]=qy[i];
v=lower_bound(rk+1,rk+sz+1,qy[i])-rk;
for(int j=qx[i]; j<=n; j+=lowbit(j))
upd(1,sz,rt[j],rt[j],v,1);
}
}
return 0;
}