P3380 【模板】树套树 的代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=5*1e4;
const int maxm=500;
const int inf=1e8;
int n,m;
int root;
int a[maxn+5];
namespace BT{
struct Node{int ls,rs,sz,pri,v;};
int tt;
Node T[maxn*maxm+5];
mt19937 rnd(time(0));
inline int New(int v){
tt++;
T[tt].sz=1,T[tt].pri=rnd(),T[tt].v=v;
return tt;
}
inline void Pushup(int rt){
if(!rt) return;
T[rt].sz=T[T[rt].ls].sz+1+T[T[rt].rs].sz;
}
void Split(int rt,int &rtx,int &rty,int v){
if(!rt) rtx=rty=0;
else if(v<T[rt].v){
rty=rt;
Split(T[rty].ls,rtx,T[rty].ls,v);
Pushup(rty);
}
else{
rtx=rt;
Split(T[rtx].rs,T[rtx].rs,rty,v);
Pushup(rtx);
}
}
int Merge(int rtx,int rty){
if((!rtx)||(!rty)) return rtx|rty;
else if(T[rtx].pri<T[rty].pri){
T[rtx].rs=Merge(T[rtx].rs,rty);
Pushup(rtx);
return rtx;
}
else{
T[rty].ls=Merge(rtx,T[rty].ls);
Pushup(rty);
return rty;
}
}
inline void Insert(int &rt,int v){
int rtx,rty;
Split(rt,rtx,rty,v);
rt=Merge(Merge(rtx,New(v)),rty);
}
inline void Delete(int &rt,int v){
int rtx,rty,rtt;
Split(rt,rtx,rty,v);
Split(rtx,rtx,rtt,v-1);
rt=Merge(rtx,rty);
}
inline int Querysz(int &rt,int l,int r){
int rtx,rty,rtt;
Split(rt,rtx,rty,r);
Split(rtx,rtx,rtt,l-1);
int tmp=T[rtt].sz;
rt=Merge(Merge(rtx,rtt),rty);
return tmp;
}
}
namespace ST{
struct Node{int ls,rs,rt;};
int tt;
Node T[maxn*maxm+5];
void Modify(int &x,int L,int R,int p,int v,int op){
if(!x) x=++tt;
if(op) BT::Delete(T[x].rt,v);
else BT::Insert(T[x].rt,v);
if(L==R) return;
else{
int mid=(R-L)/2+L;
if(p<=mid) Modify(T[x].ls,L,mid,p,v,op);
else Modify(T[x].rs,mid+1,R,p,v,op);
}
}
int Queryrk(int x,int L,int R,int p,int l,int r){
if(!x) return 0;
if(L==R) return BT::Querysz(T[x].rt,l,r);
else{
int mid=(R-L)/2+L,res=BT::Querysz(T[T[x].ls].rt,l,r);
if(p<=mid) return Queryrk(T[x].ls,L,mid,p,l,r);
else return res+Queryrk(T[x].rs,mid+1,R,p,l,r);
}
}
int Querykth(int x,int L,int R,int l,int r,int k){
if(L==R) return L;
else{
int mid=(R-L)/2+L,res=BT::Querysz(T[T[x].ls].rt,l,r);
if(k<=res) return Querykth(T[x].ls,L,mid,l,r,k);
else return Querykth(T[x].rs,mid+1,R,l,r,k-res);
}
}
}
signed main(){
int op,p,l,r,k;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
ST::Modify(root,0,inf,a[i],i,0);
}
while(m--){
scanf("%d",&op);
if(op==1){
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",ST::Queryrk(root,0,inf,k-1,l,r)+1);
}
else if(op==2){
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",ST::Querykth(root,0,inf,l,r,k));
}
else if(op==3){
scanf("%d%d",&p,&k);
ST::Modify(root,0,inf,a[p],p,1);
a[p]=k;
ST::Modify(root,0,inf,a[p],p,0);
}
else if(op==4){
scanf("%d%d%d",&l,&r,&k);
p=ST::Queryrk(root,0,inf,k-1,l,r);
if(p==0) puts("-2147483647");
else printf("%d\n",ST::Querykth(root,0,inf,l,r,p));
}
else{
scanf("%d%d%d",&l,&r,&k);
p=ST::Queryrk(root,0,inf,k,l,r);
if(p==BT::Querysz(ST::T[root].rt,l,r)) puts("2147483647");
else printf("%d\n",ST::Querykth(root,0,inf,l,r,p+1));
}
}
return 0;
}