javaee论坛

普通会员

225648

帖子

353

回复

367

积分

楼主
发表于 2019-11-03 06:59:40 | 查看: 235 | 回复: 2

我仅一届平凡人LCT(LinkCutTree)可以看作是Splay树维护的树链剖分。我们可以在一个动态树(森林)上维护树链信息。

重链剖分与实链剖分

类比树链剖分的重链剖分:在Splay树的基础上,我们定义一条实边:

一个节点的孩子节点指向一个节点,这个孩子节点的fa指针也指向这个节点(即双向边)

相对性的,我们定义一条虚边

一个节点的孩子节点指向一个节点,这个孩子节点的fa指针不指向这个节点(即但向边)

我们把一个区块里的所有实边连接起来,构成一个Splay树。实链的顶部被称为这个splay树的根,在这种结构基础上。我们定义几种操作。

1.splay

和普通splay树一样,我们将一个点伸展到根节点

2.access

从一个节点x,将其到原树根节点建立一条全部都是实边的路径。

1.将该节点伸展至当前splay的根节点2.将虚边上这个点的右孩子连接上这个根节点(虚边实化)3.向上更新后继续向上伸展(对x的fa节点)

3.mkroot

给原树换根。我们可以想象,我们如果把一颗树的节点当成根节点,只要把此节点到原根节点的路径进行调换就ok了。所以我们执行:

1.对x进行access操作。此时,x变成该splay树的最右边的节点(因为我们在access操作时,每到虚边我们都把它的根节点连接到上个节点的右孩子)2.将x伸展至根节点(x此时必没有右孩子)3.整体反转(从x开始)这条实链

4.findroot

寻找该节点的splay树的根节点

1.对x进行access。2.伸展x至根节点(此时x的根节点在当前树的最左端)3.向左递归至最低4.伸展该节点至根节点(防止数据卡链)5.返回该节点

5.link

将x,y进行连边(操作1)

1.对x进行mkroot。2.判断y的splay树的根节点是否为x,如果是直接return3.将x的fa节点指向(建立虚边)

6.cut

对x,y进行断边(操作2)

1.对x进行mkroot。2.如果x,y不在一个树上,或者是x,y不是挨着的,直接return3.断双向边

7.split

把x,y的路径拆出来

1.对x进行mkroot2.对y进行access3.对y进行splay

经过这些操作,我们发现,y此时是根结点,且y没有右孩子,左孩子是x,此时就可以访问有关y的任何操作了。

至此基本思路讲完(真的醉了)。


普通会员

0

帖子

307

回复

318

积分
沙发
发表于 2019-12-20 22:26:02

如果这就是爱,再转身的时候就该留下

普通会员

1

帖子

324

回复

336

积分
板凳
发表于 2023-11-04 10:45:38

很好

您需要登录后才可以回帖 登录 | 立即注册

触屏版| 电脑版

技术支持 历史网 V2.0 © 2016-2017