• 学习笔记::lct


    我已经忘了lct

    1.lct能干什么

    能维护一个序列,能做线段树做的事

    能维护一颗静态的树,能做树链剖分和线段树做的事

    能维护一个动态的序列,能做splay做的事

    能维护一颗动态的树,能做splay和树链剖分的事

    所以lct=splay+树链剖分 

    2.怎么维护

    树链剖分是利用轻重链剖分的性质

    那么lct也要维护轻重链,只不过由于有加边和删边所以随时在变化

    lct是由若干颗splay组成的,每颗splay代表了一条重链,splay的关键字是深度

    在树链剖分里,每次是对一条重链进行操作,然后爬到链顶的父亲进入下一条重链

    所以每一颗splay的根节点的父亲就是下一条重链的某个位置

    这里splay的父亲和孩子是不对应的,也就是说b是a的父亲,但a不一定是b的孩子

    孩子对应的是重链,父亲对应的是轻链

    3.操作

    所有的link cut都是基于access这一个操作

    access(x)操作是指将x到根的链变为重链,并且x为最深的点

    怎么实现?因为现在x到根的路径是由很多条重链组成的,现在我们要将这些重链重构变成一条重链

    考虑暴力,我们先爬到上一条重链,这个过程是先把x splay到根,那么x的父亲就是上一条重链中的某个位置y,那么我们要把y之后的重链换为x

    由于splay维护的是深度,那么x自然是比上一条重链中所有点都要深的,所以我们把ch[y][1]=x,fa[x]=y,相当于强制切换了重链

    重复这个过程直到到达根

    这个复杂度均摊是log的

    然后一系列操作由此衍生

    换根:先access(x),将路径提取出来,那么这棵splay里就是x->root构成的重链,然后splay(x),由于x是最深的,那么ch[x][0]=0,所以这个时候我们对换左右儿子就相当于把x的深度变成最浅的了,也就实现了换根

    也就是access(x) splay(x) paint(x)

    link(x,y):x连到y下面,那么把x当成y的轻儿子,直接rever(x),fa[x]=y

    cut(x,y):提取出(x,y)的路径,rever(x),access(y) splay(y),那么x->y的路径就到了一颗splay里,由于x和y相连,并且x现在比y浅,那么x肯定在y的左儿子,直接ch[y][0]=0 fa[x]=0,并且upd(y)

    单点加:直接加到对应的点上然后splay一下就行了,lct中编号对应的是原树的编号

    区间加:提取出路径,然后就打个标记

  • 相关阅读:
    Sendkeys 和 Sendmessage 使用技巧一例
    和菜鸟一起学算法之二分法求极值问题
    和菜鸟一起学算法之三分法求极值问题
    和菜鸟一起学证券投资之国内生产总值GDP
    和菜鸟一起学OK6410之Led字符驱动
    和菜鸟一起学OK6410之最简单驱动模块hello world
    和菜鸟一起学OK6410之交叉编译hello world
    和菜鸟一起学android4.0.3源码之touchscreen配置+调试记录
    和菜鸟一起学android4.0.3源码之红外遥控器适配
    和菜鸟一起学OK6410之最简单字符驱动
  • 原文地址:https://www.cnblogs.com/19992147orz/p/8206693.html
Copyright © 2020-2023  润新知