博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LCT学习笔记
阅读量:5908 次
发布时间:2019-06-19

本文共 1829 字,大约阅读时间需要 6 分钟。

link-cut-tree 是一种维护森林的数据结构,可以在log的时间内完成修改、查询链上信息等操作 。

实链剖分

我们知道,树链剖分通过划分轻重链,保证了一个点到根最多有log跳轻链和log条重链从而保证复杂度为log。

而LCT通过把每条边划分成实边和虚边,把整棵树拆成若干部分,每部分在原树中是深度严格递增的一条链(相当于是自上而下的一条链)。

而我们的每一部分都是用splay去维护的,而在每棵splay中点的深度也是严格递增的。

对于每一条实边,父亲都有连向儿子的一条边,儿子也有连向父亲的边。

对于每一条虚边,只有儿子连向父亲的边。

下面我们了解一下LCT的各种操作。

access

我们定义access(x)为,打通一条从x到整颗树的根的一条实链。

打通之后,x所在的splay中只有x到根这条链上的的所有点。

首先我们明确,对于一颗splay中某个点x,ch[x][0]中所有点的深度都是比它小的,ch[x][1]中所有点的深度都是比它大的。

若fa[x]=y那么y的深度一定比x小。

那么首先我们把x splay一下,然后我们把它的右儿子断成虚边,因为这部分我们不希望它出现在最后的splay里(因为x要成为splay里深度最大的点)。

然后我们把指针指向fa[x],令其为y,我们再去splay(y),这是我们也需要把y的右儿子断掉,然后向x连一条重边。

然后上述过程一直重复就好了,代码如下。

inline void access(int x){    for(int y=0;x;y=x,x=fa[x])splay(x),ch[x][1]=y,pushup(x);}

makeroot

我们定义makeroot(x)为把x当做整颗splay的根。

首先我们肯定要access(x),让它和根在一颗splay里。

考虑x成为根之后,整棵树相对深度发生变化的点只存在于这颗splay中,而且相对深度和原来是完全相反的,所以我们只需要在splay(x),使x成为根节点后reverse整颗splay就好了。

代码长这样:

inline void makeroot(int x){access(x);splay(x);rev[x]^=1;}

split

我们定义split(x,y)为找到x到y的一条路径。

如果上面的东西都理解了,这个就好说了。

inline void split(int x,int y){    makeroot(x);access(y);splay(y);}

findroot

我们定义findroot(x)为找到x所在树的根。

我们先access一下,在splay一下,因为根是整颗splay里深度最浅的点,所以我们一直往左儿子找就好了。

注意pushdown

inline int findroot(int x){    access(x);splay(x);pushdown(x);    while(ch[x][0])x=ch[x][0],pushdown(x);    return x;}

link

我们定义link(x,y)为连接一条x到y的虚边。

我们先makeroot x,直接令fa[x]=y即可,不难理解。

注意判不合法情况

inline void link(int x,int y){    if(findroot(x)===findroot(y))return;    makeroot(x);fa[x]=y;}

cut

我们定义cut(x,y)为切断x到y的边。

我们先split出x到y的链。

然后我们要判断当前是否存在x到y的边。

令x为根,y为splay的根,那么ch[y][0]=x,ch[y][1]=0,fa[x]=y若三个条件同时满足那么我们可以切断这条边 。

inline void cut(int x,int y){    if(findroot(x)!=findroot(y))return;    split(x,y);    if(fa[x]!=y||ch[y][1]||ch[y][0]!=x)return;    fa[x]=ch[y][0]=0;}

LCT的概念和基本操作就是这么多,感觉这里面也有很多十分玄妙的地方,不过感性理解就好了。

未完待续。。。

转载于:https://www.cnblogs.com/ZH-comld/p/10121523.html

你可能感兴趣的文章
HttpClient使用线程锁synchronized
查看>>
(高德地图)marker定位 bug 解决总结
查看>>
堆表和%%lockres%%函数
查看>>
Android 摇一摇 之 震动片
查看>>
语言学习目标
查看>>
微信公众平台开发教程(七)安全策略
查看>>
Visual Studio 添加SVN插件
查看>>
BZOJ [ZJOI2008]泡泡堂BNB 贪心
查看>>
.net IL 指令速查
查看>>
简单的工具LogUtil、Toast
查看>>
poj 2182 Lost Cows(段树精英赛的冠军)
查看>>
spring3.0结合Redis在项目中的运用
查看>>
模块命名空间
查看>>
HDU1050 Moving tables
查看>>
1.1经典软件过程模型的特点
查看>>
javac编译错误: 编码UTF8/GBK的不可映射字符
查看>>
numpy add
查看>>
Mac下Android绘制点9格式png以及解决IllegalArgumentException: Unknown image type 0报错
查看>>
Go -- 在Go语言中使用JSON struct
查看>>
mariaDB安装完成后设置root密码等初始化操作
查看>>