LCT介绍

来源:互联网 发布:linux grep -ef|ps 编辑:程序博客网 时间:2024/06/10 11:35

偶然看到了LCT,发现好多东西都忘了,今天就来写写LCT总结吧。

LCT=link-cut-tree 在树链剖分里我们把树按dfs序换成连续序列,再来解决树上两点间路径操作的问题。很明显,假如树的结构变了,那么原来的树链剖分就GG了。为了解决可以增边的问题我们引进LCT。

LCT的基本思想就是把树链剖分里的重块都存到一颗splay里,以splay的灵活性来解决删边加边的问题(无论原图怎么删都得是一棵树,这是大前提)。

对于具体操作,我来解释一下模板。。。。。。具体原理可以自己去看集训队论文。。。。

一开始每个点都是独立的。tr数组是记每个splay里的树的连接情况的(注意,仅仅是每个重链的连接情况,只看tr数组的话是不能还原树的形态的),fa数组是记每个点的父节点,很明显是可以用fa来还原树的形态的。与splay不同的是LCT里fa[a]是b 但tr[b][0]和tr[b][1]可能都不是a,再次强调(tr数组只是记录每个splay里的树的连接情况

access操作:将某个点与当前整棵树的树根连起来,类似于树链剖分里不断往上爬的步骤,这里一般将从根往上连的链接在下一个要连的点的右子树上(都是作重链,直接并在一个splay上)

makeroot操作:将某个点与当前整棵树的树根连起来,并通过splay转换到根,由于要作根的点是从底部一路连到根的所以它的深度最大,reverse一下使它变成深度最小的点。大多数博客就此停止了,为什么这样是对的?我个人认为是这样的:由于都是连在右子树,access第二个点时一定也会连在右子树上。

如果两个点在同一棵子树上并无影响,然而如果出现上图点1和点2的情况,红色的点时有用点,绿色点为无用点。我们可以发现按关键字来比较,比1点大的点都是无用点,这些点在access(1) splay(1)后在1点的左侧(1只是记号),而access(2)红圈内的点就被忽略了,所以要reverse。当然如果1,2点交换位置只是一个类似的问题。

link操作和cut操作只是make_root和access的一点套路用法而已,具体看代码就好了。

打标记的话pushdown pushup和splay类似 要记得access每次连新点时一定要pushup


http://blog.csdn.net/ied98/article/details/43877341 一个LCT基本操作的题



原创粉丝点击