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

[]Link Cut Tree

时间:2017-12-21 20:43:54      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:查询   基于   功能   png   splay   16px   roo   删除   顺序   

坑了好久,本来打算就这样弃着,最近又被神秘力量驱使来学这个东西,过程很痛苦但最终还是知道它到底是啥了

它可以用来对森林进行各种操作,为了快速地实现各种操作,我们要像树剖一样把整个森林剖成许多条链,每条链都用splay维护

为了在splay中体现链中节点的相对顺序,splay以节点深度为关键字(从小到大)

不同链之间的连接通过splay根节点的父亲来体现

技术分享图片

如图中所示,假设链$a$的splay根节点为$p$,链$b$中的节点$x$与链$a$相连,那么我们让$fa_p=x$

把森林剖成这些链之后,我们需要对其进行各种操作,比如形态改变和路径信息查询

所有的操作都基于一个东西:access

access($x$),就是“访问”节点$x$

感性地理解,一般访问树中的节点都要从树根开始走,所以这个操作实际上就是把$x$到根路径上的点都弄到一棵splay里

实现不难,我们需要从$x$按照链一直往上跳,遇到非链的边就把它连到$x$所属的链上,并把涉及到的其他链适当断开

技术分享图片

具体点,给一个真代码

void access(int x){
	int y=0;
	while(x){
		splay(x);
		ch[x][1]=y;
		pushup(x);
		y=x;
		x=fa[x];
	}
}

代码中的$y$表示当前链往下一条链的splay根节点,当执行splay($x$)后,$x$以及$x$的左子树都是$x$往上同一条链的点(因为深度$\leq dep_x$),把它连上之前的链(深度$\geq dep_x$),然后往上跳,一直到树根就ok了

如何判断一个点$u$是否为一棵splay的根?当$lson_{fa_u}\neq u$且$rson_{fa_u}\neq u$时,说明$u$是一棵splay的根节点(因为根节点的父亲指向另一条链的节点)

这样我们就完成了lct中的核心操作access,接下来用这个access随意乱搞就可以实现各种功能了

1.makeroot($x$):钦点$x$为树的根

void makert(int x){
	access(x);
	splay(x);
	reverse(x);
}

假设原来的根为$r$,因为原来深度从小到大是$r\rightarrow x$,现在变为$x\rightarrow r$,所以深度的相对大小反了,所以需要把整棵splay区间翻转

2.link($x$,$y$):连接一条边$(x,y)$

void link(int x,int y){
	makeroot(x);
	fa[x]=y;
}

3.cut($x$,$y$):删除边$(x,y)$

void cut(int x,int y){
	makeroot(x);
	access(y);
	splay(y);
	fa[x]=0;
	ch[y][0]=0;
	pushup(y);
}

makeroot($x$)并access($y$)之后,这棵splay中就只有$x$和$y$两个节点了,断开就好

4.operate($x$,$y$):对$x\rightarrow y$这条路径做一些操作(询问,修改等)

void cut(int x,int y){
	makeroot(x);
	access(y);
	splay(y);
	//...
}

makeroot($x$)并access($y$)之后,这棵splay中只有$x\rightarrow y$路径上的点,我们可以对这棵splay做任何平衡树能做的操作

5.connected($x$,$y$):判断$x$和$y$是否在同一棵树中

bool connected(int x,int y){
	if(x==y)return 1;
	makeroot(x);
	access(y);
	splay(y);
	return fa[x]!=0;
}

如果$x$和$y$在同一棵树上,那么在makeroot($x$)并access($y$)之后,$x$和$y$就在同一棵splay上了,再splay($y$),$x$就会被挤下去,即是说$fa_x\ne0$

刚接触的时候会觉得很不可理解,但认真去画一画,调一调就知道它的含义是啥了

[]Link Cut Tree

标签:查询   基于   功能   png   splay   16px   roo   删除   顺序   

原文地址:http://www.cnblogs.com/jefflyy/p/8082257.html

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