树链剖分
树链剖分
树链剖分,就是将树剖分为若干条链,用来维护树上信息,常搭配树上值域线段树,如:
修改树上两点间的最短路径上的节点权值
查询树上两点间的最短路径上的点权和
修改以某个点为根的子树的每个节点的点权
查询以某个点为根的子树的节点权值和
其中,操作3和4可以直接建立树上值域线段树解决,操作1和2需要进行树链剖分。
树链剖分有三种方法:重链剖分(复杂度 \(O(\log n)\))、长链剖分(复杂度 \(O(\sqrt n)\))和实链剖分(常用于LCT维护)。其中,重链剖分最为常见,因此本节主要记录重链剖分的学习笔记。
一、基础定义
重儿子:一个节点的所有儿子中,子树大小最大的那一个儿子。如有多种选择,就只选一个儿子。
轻儿子:一个节点的所有儿子中,不是重儿子的节点。根节点也是轻儿子。
重链:从一个轻儿子开始,沿着重儿子走,连出的极大子链。
轻链:不是重链的子链。
重链定理\(\quad\) 除了根节点以外的任何一个节点的父亲一定在一条重链上。
二、重链剖分
重链剖分,需要我们维护一下内容:
fa[MAXN]
,即节点的父节点。dep[MAXN]
,即节点深度。son[MAXN]
,即该节点的重儿子编号,如果是叶子节点,则son[p]=0
。top[MAXN]
,即该节点所在重链的链头。sz[MAXN]
,即以该节点为根的子树的大小。dfn[MAXN]
,该节点进行 \(\text{dfs}\) 的时间戳,即该节点的 \(\text{dfs}\) 序。w[MAXN]
,即在 \(\text{dfs}\) 序中,该序号节点的权值。tick
,即 \(\text{dfs}\) 时间戳。
前面几个信息可以打包进一个结构体,然后线段树需要另一个结构体。
重链剖分要求重链上的时间戳一定要连续(方便在线段树上区间修改和查询),所以需要进行两次 \(\text{dfs}\)。
2.1\(\quad\) 第一次 \(\text{dfs}\)
第一次 \(\text{dfs}\) 需要处理出重链剖分的前置信息。
从根节点开始遍历整棵树。记录节点父亲、子树大小、深度,还有重儿子。
1 | void dfs1(int u,int fa){ |
2.2\(\quad\) 第二次 $ $
第二次 \(\text{dfs}\) 就可以剖分这棵树了。
我们进行重链剖分,记录该节点所在的重链的链头和时间戳。
1 | void dfs2(int u,int t){ |
2.3\(\quad\) 建立树上值域线段树
因为子树的 \(\text{dfs}\) 序一个区间,我们就可以建立值域线段树。
1 | void build(int l,int r,int p){ |
三、维护信息
3.1\(\quad\) 进行子树加操作
因为子树的 \(\text{dfs}\) 序是一个区间,可以在线段树上进行区间修改操作(\(\text{modify}\)),修改的区间就是 ,其\([\text{dfn}[p],\text{dfn}[p]+\text{sz}[p]-1]\)中 \(p\) 为子树根节点。
1 | void modify(int l,int r,int k,int p){ |
3.2\(\quad\)进行子树求和
类比子树加操作,在线段树上进行区间求和(\(\text{query}\)),求和区间就是 \([\text{dfn}[p],\text{dfn}[p]+\text{sz}[p]-1]\),其中 \(p\) 为子树根节点。
1 | int query(int l,int r,int p){ |
3.3\(\quad\) 进行路径修改操作
根据重连定理,除了根节点以外的任何一个节点的父亲一定在一条重链上。所以我们就可以进行重链到重链的转换,从而一点一点地在每一条链上进行区间修改。
考虑每次选择链头深度高的那条链,将该节点跳到链头并区间修改,此时就改掉了这条链(也就是路径的一部分)上的值,修改区间为 \([\text{dfn}[\text{top}[p]],\text{dfn}[p]]\),其中,\(p\) 为该节点,而后跳到链头的父亲,此时就在另一条链上了,可以重复操作直到两节点在同一条重链上。
如果两节点在同一跳重链上,则可以直接进行区间修改,修改区间为 \([\text{dfn}[x],\text{dfn}[y]]\)$,其中 \(x,y\) 是两个节点,且防止无效修改操作, \(\text{dep}[x]<\text{dep}[y]\)。
1 | void addOnTree(int x,int y,int c){ |
3.4\(\quad\) 进行路径求和操作
思想类似路径修改,只不过把修改操作改成求和。
1 | int getSumOnTree(int x,int y){ |
四、参考代码
本代码为树链剖分/重链剖分模板。
1 |
|