平衡树入门

Posted Stump

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了平衡树入门相关的知识,希望对你有一定的参考价值。

BZOJ1588

http://www.lydsy.com/JudgeOnline/problem.php?id=1588

splay维护一下前驱后继

#include<cstdio>
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
inline int min(int a,int b){
	return a<b?a:b;
}
const int N=100011,inf=(1<<30);
int num1,num2;
int n,x,ans;
namespace Splay{
	int sz,rt;
	int to[N][2],fa[N],num[N];
	inline void rotate(int x,int &k){
		register int y=fa[x],z=fa[y],l,r;
		l=(x==to[y][0]?0:1);r=l^1;
		if(y==k)
			k=x;
		else 
			to[z][0]==y?to[z][0]=x:to[z][1]=y;
		fa[x]=z;fa[y]=x;fa[to[x][r]]=y;
		to[y][l]=to[x][r];to[x][r]=y;
	}
	inline void modify(int x,int &k){
		register int y,z;
		while(x!=k){
			y=fa[x];z=fa[y];
			if(y!=k)((to[y][0]==x)^(to[z][0]==y))?rotate(x,k):rotate(y,k);
			rotate(x,k);
		}
	}
	inline void insert(int &k,int x,int father=0){
		if(!k){
			k=++sz;
			fa[k]=father;
			num[k]=x;
			modify(k,rt);
			return ;
		}
		x<num[k]?insert(to[k][0],x,k):insert(to[k][1],x,k);
	}
	inline void ask_before(int k,int x){
     	if(!k)return;
     	if(num[k]<=x){
	 		num1=num[k];
			ask_before(to[k][1],x);
		}
    	else 
			ask_before(to[k][0],x);
 	}
	inline void ask_after(int k,int x){
   		if(!k)return;
   		if(num[k]>=x){
		   	num2=num[k];
			ask_after(to[k][0],x);
		}
   		else 
		   	ask_after(to[k][1],x);
	}
}
using namespace Splay;
int main(){
	scanf("%d",&n);
	FOR(i,1,n){
		num1=-inf;num2=inf;
		scanf("%d",&x);
		ask_after(rt,x);
		ask_before(rt,x);
		ans+=(i!=1?min(num2-x,x-num1):x);
		insert(rt,x);
	}
	printf("%d",ans);
	return 0;
}

  

以上是关于平衡树入门的主要内容,如果未能解决你的问题,请参考以下文章

⭐算法入门⭐《二叉树 - 平衡二叉树》简单01 —— LeetCode 110. 平衡二叉树

Splay入门

文艺平衡树 lg3391(splay维护区间入门)

入门Splay--tarjan大佬的又一发明

数据结构与算法:树 AVL平衡二叉排序树

数据结构与算法:树 AVL平衡二叉排序树