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

平衡树入门

时间:2017-12-26 23:49:57      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:mes   cst   def   class   const   body   gis   geo   insert   

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;
}

  

平衡树入门

标签:mes   cst   def   class   const   body   gis   geo   insert   

原文地址:https://www.cnblogs.com/Stump/p/8120481.html

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