码迷,mamicode.com
首页 > 其他好文 > 详细

LCT总结

时间:2018-12-14 21:14:32      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:基本   时间   eve   oid   查询   原来   十分   maker   递增   

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的概念和基本操作就是这么多,感觉这里面也有很多十分玄妙的地方,不过感性理解就好了。

未完待续。。。

LCT总结

标签:基本   时间   eve   oid   查询   原来   十分   maker   递增   

原文地址:https://www.cnblogs.com/ZH-comld/p/10121523.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!