给定一个长度为\(n\)的序列\(\{ a \}\),需支持两种操作:查询区间\([L,R]\)中第\(k\)小的数;将\(a_{x}\)改为\(y\).
此题需支持动态区间kth查询,不难想到用主席树进行维护,然后至于单点修改操作,可以用树状数组维护前缀和.
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#define R register
#define next kdjadskfj
#define debug puts("mlg")
#define mod 10000000007
#define Mod(x) ((x%mod+mod)%mod)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
inline ll read();
inline void write(ll x);
inline void writeln(ll x);
inline void writesp(ll x);
inline ll lowbit(ll x){return x&-x;}
const ll maxn=1e6+5;
struct node{
ll op,l,r,k,x,y;
}q[maxn];
ll n,m;
ll a[maxn];
ll lsh[maxn<<1],h;
ll rt[maxn<<1],cnt;
struct seg{
ll ls,rs,dat;
}t[maxn<<4];
ll temp[2][maxn],tot[2];
inline void update(ll &p,ll l,ll r,ll k,ll val){
if(!p) p=++cnt;
t[p].dat+=val;
if(l==r) return;
ll mid=l+r>>1;
if(k<=mid) update(t[p].ls,l,mid,k,val);
else update(t[p].rs,mid+1,r,k,val);
}
inline void True_update(ll pos,ll val){
for(R ll i=pos;i<=n;i+=lowbit(i)) update(rt[i],1,h,a[pos],val);
}
inline ll query(ll l,ll r,ll k){
if(l==r) return l;
ll mid=l+r>>1,sum=0;
for(R ll i=1;i<=tot[0];i++) sum+=t[t[temp[0][i]].ls].dat;
for(R ll i=1;i<=tot[1];i++) sum-=t[t[temp[1][i]].ls].dat;
if(k<=sum){
for(R ll i=1;i<=tot[0];i++) temp[0][i]=t[temp[0][i]].ls;
for(R ll i=1;i<=tot[1];i++) temp[1][i]=t[temp[1][i]].ls;
return query(l,mid,k);
}
else{
for(R ll i=1;i<=tot[0];i++) temp[0][i]=t[temp[0][i]].rs;
for(R ll i=1;i<=tot[1];i++) temp[1][i]=t[temp[1][i]].rs;
return query(mid+1,r,k-sum);
}
}
inline ll True_query(ll l,ll r,ll k){
tot[0]=tot[1]=0;
for(R ll i=r;i;i-=lowbit(i)) temp[0][++tot[0]]=rt[i];
for(R ll i=l-1;i;i-=lowbit(i)) temp[1][++tot[1]]=rt[i];
return query(1,h,k);
}
int main(){
n=read();m=read();
for(R ll i=1;i<=n;i++) a[i]=lsh[++h]=read();
for(R ll i=1;i<=m;i++){
char wn=getchar();
while(wn!=‘Q‘&&wn!=‘C‘) wn=getchar();
if(wn==‘Q‘){
q[i].op=1;q[i].l=read();q[i].r=read();q[i].k=read();
}
else{
q[i].op=2;q[i].x=read();lsh[++h]=q[i].y=read();
}
}
sort(lsh+1,lsh+h+1);
h=unique(lsh+1,lsh+h+1)-lsh-1;
for(R ll i=1;i<=n;i++) a[i]=lower_bound(lsh+1,lsh+h+1,a[i])-lsh;
for(R ll i=1;i<=n;i++) True_update(i,1);
for(R ll i=1;i<=m;i++){
if(q[i].op==1){
writeln(lsh[True_query(q[i].l,q[i].r,q[i].k)]);
}
else{
True_update(q[i].x,-1);
a[q[i].x]=lower_bound(lsh+1,lsh+h+1,q[i].y)-lsh;
True_update(q[i].x,1);
}
}
}
inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘) t=-1;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}return x*t;}
inline void write(ll x){if(x<0){putchar(‘-‘);x=-x;}if(x<=9){putchar(x+‘0‘);return;}write(x/10);putchar(x%10+‘0‘);}
inline void writesp(ll x){write(x);putchar(‘ ‘);}
inline void writeln(ll x){write(x);putchar(‘\n‘);}
原文:https://www.cnblogs.com/ylwtsq/p/13455285.html