码迷,mamicode.com
首页 > 其他好文 > 详细

Splay模板(可能有Bug)

时间:2017-12-23 20:20:48      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:const   arp   turn   push   insert   string   lin   ons   ios   

注意问题:1、如果某个指针移动了,要判断好与其他语句的先后关系

                  2、习惯于打初始化

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn=100009;

int T;
int nn,root;
int fa[maxn],ch[maxn][2],siz[maxn],cnt[maxn],ky[maxn];

int Splayinit(){
	nn=root=0;
	fa[0]=ch[0][0]=ch[0][1]=siz[0]=cnt[0]=ky[0]=0;
}

inline int son(int x){
	return (ch[fa[x]][1]==x);
}
inline int pushup(int x){
	siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+cnt[x];
}

int Rotate(int x){
	int y=fa[x];
	int z=fa[y];
	int b=son(x),c=son(y);
	int a=ch[x][b^1];
	if(z)ch[z][c]=x;
	else root=x;
	fa[x]=z;
	if(a)fa[a]=y;
	ch[y][b]=a;
	fa[y]=x;ch[x][b^1]=y;
	pushup(y);pushup(x);
}
int Splay(int x,int i){
	while(fa[x]!=i){
		int y=fa[x];
		int z=fa[y];
		if(z==i){
			Rotate(x);
		}else{
			if(son(x)==son(y)){
				Rotate(y);Rotate(x);
			}else{
				Rotate(x);Rotate(x);
			}
		}
	}
}

int Getp(int val){
	int x=root;
	while(x){
		if(ky[x]==val){
			Splay(x,0);return 0;
		}
		if(val>ky[x])x=ch[x][1];
		else x=ch[x][0];
	}
}
int Getpre(int val){
	int x=root,ret=0;
	while(x){
		if(ky[x]>=val){
			x=ch[x][0];
		}else{
			ret=ky[x];
			x=ch[x][1];
		}
	}
	return ret;
}
int Getsuf(int val){
	int x=root,ret=0;
	while(x){
		if(ky[x]<=val){
			x=ch[x][1];
		}else{
			ret=ky[x];
			x=ch[x][0];
		}
	}
	return ret;
}

int Insert(int val){
	int x=root,y=0;
	while(x){
		y=x;
		if(ky[x]==val){
			++cnt[x];++siz[x];
			Splay(x,0);return 0;
		}
		if(val>ky[x])x=ch[x][1];
		else x=ch[x][0];
	}
	x=(++nn);
	fa[x]=y;ch[x][0]=ch[x][1]=0;
	siz[x]=cnt[x]=1;ky[x]=val;
	if(y==0){
		root=x;
	}else{
		if(val>ky[y])ch[y][1]=x;
		else ch[y][0]=x;
	}
	Splay(x,0);
}

int Del(int val){
	Getp(val);
	int x=root;
	if(cnt[x]>1){
		--cnt[x];--siz[x];return 0;
	}
	
	if((ch[x][0]==0)&&(ch[x][1]==0)){
		root=0;
	}else if(ch[x][0]==0){
		root=ch[x][1];fa[ch[x][1]]=0;
	}else if(ch[x][1]==0){
		root=ch[x][0];fa[ch[x][0]]=0;
	}else{
		int p=ch[x][0];
		while(ch[p][1])p=ch[p][1];
		Splay(p,x);
		ch[p][1]=ch[x][1];fa[ch[x][1]]=p;
		root=p;fa[p]=0;pushup(p);
	}
}

int Rank(int val){
	Insert(val);
	int ret=siz[ch[root][0]]+1;
	Del(val);
	return ret;
}
int Kth(int k){
	int x=root;
	for(int l;;){
		l=ch[x][0];
		if(k<=siz[l]){
			x=ch[x][0];
		}else if(k>siz[l]+cnt[x]){
			k-=(siz[l]+cnt[x]);
			x=ch[x][1];
		}else{
			return ky[x];
		}
	}
}

int main(){
	scanf("%d",&T);
	while(T--){
		int opty,x;
		scanf("%d%d",&opty,&x);
		if(opty==1)Insert(x);
		if(opty==2)Del(x);
		if(opty==3)printf("%d\n",Rank(x));
		if(opty==4)printf("%d\n",Kth(x));
		if(opty==5)printf("%d\n",Getpre(x));
		if(opty==6)printf("%d\n",Getsuf(x));
	}
	return 0;
}

  

Splay模板(可能有Bug)

标签:const   arp   turn   push   insert   string   lin   ons   ios   

原文地址:http://www.cnblogs.com/zzyer/p/8094158.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!