动态树
—维护树的连通性的强力武器
功能
LCT(link-cut tree)支持树(森林)的link,cnt,换根(makeroot)等等操作,而且也能维护树上的权值。
实现比较神奇。每个点都有一个preferred son。但是这不一定是由子树大小来决定的。他们两个之间的边称为preferred edge。
动态树使用更加灵活的Splay来实现。对于一段连续的边,即一条由preferred edge组成的preferred path上的点,保存在同一颗Splay中。Splay按深度关系来维护这些点。同时根节点的父亲指向当前Splay中深度最浅的点在原树中的父亲,但是这个父亲的儿子并不是这个点,所以可以依据这个来判断是不是根。
由以下核心操作来实现
Access x 将x到根节点的路径变为preferred path
Split x y 将x,y变到同一个Splay中
代码
|
|
每个操作的实现都比较清晰明了。
例题
弹飞绵羊(bzoj 2002)
只包括简单地连边操作。对于每一个会跳飞的结点,我们可以设置一个结点,即n+1来连边。事实上一个点能跳的步数就是将这棵树反过来之后(makeroot)在Splay上的左儿子的size,即深度比其浅的点。
COGS动态树
这题是FoolMike大佬刚出的啊。这题需要一些奇怪的操作,维护子树大小的信息。但是普通的LCT不能搞啊。我们需要在树上再记录一个信息,即其非preferred son的子树大小,然后size去掉这个。这样的话,就可以在access的时候灵活地修改了
但是好像还有别的高级LCT可以解决这个问题啊
留一个tag