严重声明!!!
这只是部分的学习笔记,避免遗忘我先简记下来,对于一些没讲清楚的地方,我深表抱歉。可以结合我的博客参考一下其他大神的博客。
简介
LCT是动态树中的一种。
结合了splay的知识。
它维护原树的信息。
支持很多骚操作。
如果splay不熟,请自行劝退。
我将最重要的内容写一写就好了。
基础知识
在原树中,每个非叶子节点都会有一个偏爱儿子,它与偏爱儿子的边叫偏爱边。
连在一起的偏爱边会连成偏爱链。
LCT通过偏爱链来维护原树信息。
这棵LCT内,一棵SPLAY代表一条偏爱链。
一开始的时候,有多个LCT。
图以后再画。
骚操作
严重声明!
一下操作只是最基本的操作,如果要应用到题目中,必须结合题意,巧妙地维护信息。
LCT只是一个处理动态树信息的工具。
Access(x)
A
c
c
e
s
s
(
x
)
这是LCT中最基本的一个骚操作。
就是将x与原树中x的根打通。
具体操作?
1.splay(x) 将x旋到x的splay的根。
2.断掉x与右儿子的边。注:此时x已经是它所在的splay的根了,所以它LCT的”父亲”y(y的儿子里没有x)和x所在的子树的最左边的点(也就是原树的偏爱链的顶)之间的边不是偏爱边,此时需要将这条边转换成偏爱边。所以y的偏爱儿子应该发生变化。
3.y在LCT中的右儿子标记为x
4.x=y,直到fa[x]=0
PS!!这里的splay是要旋到splay的根,不能直接用fa[x]!=0继续往上跳,应该用isroot。
Mroot(x)
M
r
o
o
t
(
x
)
这个骚操作就是将x变成它所在的LCT的根,通常可以使这条偏爱路径的信息集中到这个点上。
1.Access(x) 显然要打通到原树的根的路径。
2.Splay(x)
3.把整个Splay旋转(即打个旋转标记)。
解释:如果只进行了1和2操作,那么x仍在x到树根的偏爱路径的最底端(深度最大),现在要让x变成根,所以打个旋转标记就好了。
Groot(x)
G
r
o
o
t
(
x
)
意为getroot。即得到x所在的树的根。
1.Access(x)
2.一直走x的splay的左儿子。
时间复杂度
O(log)
O
(
l
o
g
)
Link(x,y)
L
i
n
k
(
x
,
y
)
给节点x,y连接一条边,使得x的LCT与y的LCT连接起来。
1.Mroot(x)
2.fa[x]=y
操作1、2是link(x,y)最根本的操作,若要维护更多的信息,请动用自己的聪明才智。
Cut(x,y)
C
u
t
(
x
,
y
)
我之前学到这里就被卡住了。
原因,如果在原树中,x和y是属于同一棵LCT的,但是他们之间没有边相连,这里要特判。
1.Mroot(x)
2.Access(y)
3.splay(y)
4.pushdown(x)//下传各种标记(例如旋转标记)
还没完。
解释:3操作,如果x是y的左边第一个(即暴力从y的左儿子一直往右跳)说明在原树中,x和y有边相连,否则没有。
这个操作叫特判。
特判的时间复杂度:
O(log)
O
(
l
o
g
)
5.
son[y][0]=0,fa[son[y][0]]=0
s
o
n
[
y
]
[
0
]
=
0
,
f
a
[
s
o
n
[
y
]
[
0
]
]
=
0
断掉y和左儿子的连边。
PS:不要忘记维护相关信息。
基本操作就这些了。