首页 > 其他 > 详细

LCT

时间:2019-05-05 01:15:16      阅读:171      评论:0      收藏:0      [点我收藏+]

我透,我之前学的时候写的笔记没存...

现在忘了又要重学一遍...

大佬的讲解

我只写一些摘录和旁批(主要是背代码的细节..
首先,LCT:

在实链剖分的基础下,LCT资磁更多的操作

  • 查询、修改链上的信息(最值,总和等)
  • 随意指定原树的根(即换根)
  • 动态连边、删边
  • 合并两棵树、分离一棵树
  • 动态维护连通性

LCT性质:

    1. 每一个Splay维护的是一条从上到下按在原树中深度严格递增的路径,且中序遍历Splay得到的每个点的深度序列严格递增。

    2. 每个节点包含且仅包含于一个Splay中

    3. 边分为实边和虚边,实边包含在Splay中,而虚边总是由一棵Splay指向另一个节点(指向该Splay中中序遍历最靠前的点在原树中的父亲)。
      因为性质2,当某点在原树中有多个儿子时,只能向其中一个儿子拉一条实链(只认一个儿子),而其它儿子是不能在这个Splay中的。
      那么为了保持树的形状,我们要让到其它儿子的边变为虚边,由对应儿子所属的Splay的根节点的父亲指向该点,而从该点并不能直接访问该儿子(认父不认子)。

关于pushup,pushdown:

每次从下到上,操作后要pushup

每次从上到下操作要pushdown

千万别忘了

access:

  access即定义为打通根节点到指定节点的实链,使得一条中序遍历以根开始、以指定点结束的Splay出现。

void access(int x){
    for(int y=0;x;y=x,x=f[x])
        splay(x),c[x][1]=y,pushup(x);//儿子变了,需要及时上传信息
}

  

makeroot:

 

换根,让指定点成为原树的根。

这时候就利用到access(x)和Splay的翻转操作。
access(x)x在Splay中一定是深度最大的点。
splay(x)后,x在Splay中将没有右子树(性质1)。

于是翻转整个Splay,使得所有点的深度都倒过来了,x没了左子树,反倒成了深度最小的点(根节点),达到了我们的目的。

 

LCT

原文:https://www.cnblogs.com/Hikigaya/p/10810564.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!