既见君子

临床大四在读/坐标上海/一个挣扎着也热爱着的医学生

LCT学习笔记  

既然大家都说LCT是我在砍树,我也得好好砍不是,所以认真学习了一下Link-Cut-Tree然后来做笔记了。//某lxl看到我就狂D“您是在砍树吗”,真是气人至极

Link-Cut-Tree,顾名思义,最有特色的地方就在Link和Cut。

与链剖相似的是,它也是时常用来维护树链上信息的,但有不同的是,链剖对于每一个非叶子节点一定选一个儿子(重儿子)相连,且一旦连上就不会变,而LCT的每个非叶子节点所选来连的儿子数<=1,还总是变.如果要打个详细的比方的话,那链剖就是木心的从前慢里面的那把锁,锁上之后别人就懂了,而LCT就像当今的新时代青年,可以不结婚,也可以结婚,也可以结了婚离婚再结婚。总之,变脸比翻书还快,但正是因为这样,才自由可变化,适用范围更广。

LCT,因为动态是动态树,所以也要用动态的数据结构来维护,这里选用Splay。

Question1:

  Splay维护什么?

以深度为键值,维护链上信息(但我们其实并不需要真正的在节点信息里面记上深度),splay可支持的所有信息操作。

Question2:

这么多棵splay那一定有很多根吧,那岂不是根满天飞!

不不不你太天真了,我们只是换了一种判断根的方式,每一棵splay的根的father是原树上这条链深度最浅的那个点的father。


下面介绍LCT一些基本操作:

0.isroot(u)判断u是否是splay上的根节点

1.access(u)表示将u到根节点这条链变成实链,并将u到u的儿子断掉。

2.makeroot(u)将u变为新的根

access(u)+reverse(u)//reverse是splay里的操作

为什么这样?因为原来是按照深度为键值建的splay,我如今要换根,那么u的深度一定要变为最小,u的father次小这样依次类推。巧妙地发现只用翻转一下splay区间就好啦~

3.link(u,v)将本不联通的u,v连上一条边

  makeroot(u)

u->pre=v;//这里连的是虚边,所以并不管v的儿子是不是u

access(v)//其实我并不知道这里为什么大家都会习惯性的写个access,以后其实会access并更新信息的

4.cut(u,v)将本在树上有连边的u和v之间的这一条边断掉

  makeroot(u)

access(v)//v不是根则v的深度一定比u大,在u的右子树上,而因为直接连边,所以是他的右儿子

splay(v)//此时u变成了v的左儿子

  v->ch[0]=nil;

  u->pre=nil;'//删掉

基本的操作就这些,本来我也是不怎么会写的,看了zcy朱神的代码之后觉得神清气爽好看极了就跟着他的板一起写了。


下面贴板

//小小感怀一下,noip之前我还是个连splay都不敢写的naive少年LCT更是不敢想,果然人是需要迈步的勇气的阿!

//本来朱神的板我的zzk他是写的hja,我一想不敢亵渎仰慕的大神就只好换啦


评论
热度(1)
©既见君子
Powered by LOFTER