• 【动态树】初识


    参考】:我觉得写得最清楚的一个:https://oi.men.ci/link-cut-tree-notes/

    https://www.cnblogs.com/flashhu/p/8324551.html

                      论文什么的太专业了我一半没耐心去看:https://wenku.baidu.com/view/75906f160b4e767f5acfcedb

    背景】:反正就是拖了很久,然后最近稍微练习了一下splay和树剖之后才有勇气去看,因为三个月前看晕了,然后就一搁着了。

                      但是最近遇到了LCT解决可以删边的并查集问题,是时候补一波了。

    主要会晕的原因就是有两棵树:splay树和原树,如果博主没写清楚,或者理解不到位就可能搞晕。

    现在大概看懂后理解是这样的:原树是虚拟的,用来满足我们的常识。 而真正的操作基本上都是在splay树上的,只是splay树上的操作要满足原树也成立。

                                                      所以加边、删边操作需要把节点移到splay树的根节点;同时,由于splay到根,为了满足原树的形状,需要翻转操作。

    注意1:如何理解这里的一颗splay树? :一颗splay树是一个原树上的链。

                 。这个splay的根没什么特殊的,它不一定是原树的根,把它splay到根节点只是为了“加边”和“删边”等操作。

                 。这个splay的排序是根据深度的,所以“翻转”操作只需要交换左右儿子即可。

                 。原树是多叉树,splay是二叉树。有人会疑惑为什么二者能互相表示呢? 其实原树并没有记录儿子关系,只记录了父亲关系(splay树的父亲关系转化可得),但我们找X到根root的路径是没问题的(一直上找)。 而splay树则记录的父亲和儿子关系,rotate,pushdown等操作不成问题。

                 。make_root(move_to_root)是针对原树,splay是针对splay树,但是操作都是在splay树上实现

               (只要一直注意到这几点应该就不太会搞晕了)

    注意2:由于有多棵splay树,所以不能记录root节点,而需要用isroot函数判定。

    注意3:关于合并,一棵splay树上有一个par_path,它在根节点位置A,代表通过根节点连接到另外一棵树X,设B为X的根节点,连接后之前的根节点A就不是根节点了,所以A处没有par_path,新树的par_path在被连接的树X的根节点B处。

    注意4:关于查找两个节点X、Y是否在同一棵树上:因为splay的根节点是不固定的,也没有代表性,所以需要找“原树”的根节点。 具体的:把Xaceess,然后splay到根,然后就可以向左边找深度第的节点,直到找到原树的根节点。

     注意5:统计u到v的链上的信息,比如u-v链的节点权值和。和splay求区间和以及树剖的方法不同:直接在把u移到根(原树,则u深度最小),然后aceess-v(aplsy树,则v深度最大。)然后把v节点spaly到根(形如一条只有左儿子的链),就可以直接统计了,sum[X]=val[X]+sum[left_son]。

    其他的,凭借自己的想象力,就可以大概打出伪代码了。

    accessX:常规,使X到所在的根的链成为重链,从下到上。

    splayX:稍微差别,需要先pushdown。

    rotateX:常规。

    updateX:常规。

    ...‘

    所以只要有splay的基础,还是不难“入门”LCT的。

  • 相关阅读:
    九大经典算法之插入排序、希尔排序
    1072 开学寄语 (20 分)
    1070 结绳 (25 分
    查找字符串中的所有数字
    通过类继承计算梯形面积
    将命令的输出生成一个Web页面
    从Internet下载一个文件
    使用Excel管理命令输出
    将一个命令的输出保存到CSV文件
    使用属性存储用户编号和姓名
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8688321.html
Copyright © 2020-2023  润新知