luogu P3835 【模板】可持久化平衡树

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
const int maxn=500009;
const int oo=2147483647;

int T;
int nn=0;
int ch[maxn*50][2]={0},siz[maxn*50]={0},pri[maxn*50]={0},ky[maxn*50]={0};
int root[maxn]={0};

void pushup(int x){
	siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
}
int NewNode(int val){
	int x=++nn;
	ky[x]=val;
	siz[x]=1;
	pri[x]=rand();
	return x;
}
int CopyNode(int y){
	int x=++nn;
	ch[x][0]=ch[y][0];
	ch[x][1]=ch[y][1];
	pri[x]=pri[y];
	siz[x]=siz[y];
	ky[x]=ky[y];
	return x;
}

int Mer(int x,int y){
	if((!x)||(!y))return x+y;
	if(pri[x]<pri[y]){
		int p=CopyNode(x);
		ch[p][1]=Mer(ch[p][1],y);
		pushup(p);
		return p;
	}else{
		int p=CopyNode(y);
		ch[p][0]=Mer(x,ch[p][0]);
		pushup(p);
		return p;
	}
}

void Split(int now,int k,int &x,int &y){
	if(!now){
		x=y=0;
	}else{
		if(ky[now]<=k){
			x=CopyNode(now);
			Split(ch[x][1],k,ch[x][1],y);
			pushup(x);
		}else{
			y=CopyNode(now);
			Split(ch[y][0],k,x,ch[y][0]);
			pushup(y);
		}
	}
}

void Del(int &rt,int val){
	int x,y,z;
	Split(rt,val,x,z);
	Split(x,val-1,x,y);
	y=Mer(ch[y][0],ch[y][1]);
	rt=Mer(Mer(x,y),z);
}
void Ins(int &rt,int val){
	int x,y,z;
	Split(rt,val,x,y);
	rt=Mer(Mer(x,NewNode(val)),y);
}
int Kth(int x,int k){
	while(x){
		int l=ch[x][0];
		if(k<=siz[l]){
			x=ch[x][0];
		}else if(k>siz[l]+1){
			k-=(siz[l]+1);
			x=ch[x][1];
		}else{
			return ky[x];
		}
	}
}
int Rank(int x,int val){
	int ret=0;
	while(x){
		if(ky[x]<val){
			ret+=siz[ch[x][0]]+1;
			x=ch[x][1];
		}else if(ky[x]>val){
			x=ch[x][0];
		}else{
			ret+=siz[ch[x][0]];break;
		}
	}
	return ret+1;
}
int Getpre(int x,int val){
	int ret=oo;
	while(x){
		if(ky[x]<val){
			ret=ky[x];
			x=ch[x][1];
		}else{
			x=ch[x][0];
		}
	}
	return ret;
}
int Getsuc(int x,int val){
	int ret=-oo;
	while(x){
		if(ky[x]>val){
			ret=ky[x];
			x=ch[x][0];
		}else{
			x=ch[x][1];
		}
	}
	return ret;
}

void check(int x){
	if(ch[x][0])check(ch[x][0]);
	cout<<ky[x]<<' ';
	if(ch[x][1])check(ch[x][1]);
}

int main(){
	scanf("%d",&T);
	for(int i=1;i<=T;++i){
		int opty,pre,a;
		scanf("%d%d%d",&pre,&opty,&a);
		root[i]=root[pre];
		if(opty==1)Ins(root[i],a);
		if(opty==2)Del(root[i],a);
		if(opty==3)printf("%d\n",Rank(root[i],a));
		if(opty==4)printf("%d\n",Kth(root[i],a));
		if(opty==5)printf("%d\n",Getpre(root[i],a));
		if(opty==6)printf("%d\n",Getsuc(root[i],a));
//		check(root[i]);
//		cout<<endl;
	}
	return 0;
}

  

posted @ 2018-03-02 21:36  ws_zzy  阅读(186)  评论(0编辑  收藏  举报