P3380 【模板】树套树 的代码

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;
}
posted @ 2024-05-16 22:12  DeepSeaSpray  阅读(1)  评论(0编辑  收藏  举报