Dynamic Rankings(資料結構)
阿新 • • 發佈:2020-08-07
description
給定一個長度為\(n\)的序列\(\{ a \}\),需支援兩種操作:查詢區間\([L,R]\)中第\(k\)小的數;將\(a_{x}\)改為\(y\).
solution
此題需支援動態區間kth查詢,不難想到用主席樹進行維護,然後至於單點修改操作,可以用樹狀陣列維護字首和.
code
#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');}