倍增,DFS序,欧拉序
倍增,DFS序,欧拉序
一、倍增
倍增的应用
①树上
回想一下之前学的倍增法求
对于
因为
即:
倍增表打好了,那
② 的 级祖先
往上跳
1 | for(j = logn -> 0) |
举个栗子:
③记录路径信息(无修改)
预处理:

查询:时间复杂度
例题:路径最小值
1 |
|
二、DFS序
性质:子树标号连续


子树编号连续=>子树问题—转化—>序列区间问题
比如:
单点修改,查询子树和—转化—>单点修改,查询区间和(树状数组)
查询根到x点路径和(类似深度):怎么做呢?考虑对于每个点x,都在

例题
1.DFS序练习1
单点修改,子树查询,区间查询
1 |
|
2.DFS序练习2
单点修改,子树查询,换根操作
换根:
难点:我们换根之后DFS序变了
那怎么办呢?
看起来是有换根操作,但实际上我们是不换根的,我们还是在原来的树的DFS序上做,拿一个变了记录根的位置。
root = x:子树就是整棵树


根是x的子孙:
&& ,子树就是整棵树去掉 这一段。 这里为什么是:
&& 呢? 解释:
和 是dfs的顺序,显然 比 先被dfs到,那就有 ,另一边是可以等于的,因为右端点可能一样,可参考上图。 具体做法就是:从root开始倍增,如果深度比x大就往上跳,这样就能刚好跳到x的下面。更优的做法是在x儿子里面二分出l[root]在哪个区间里面,找到一个左端点<=它,右端点>=它的。

- 其他:子树还是
1 |
|
3.DFS序+奇偶性分层+线段树
题意:给一颗n个节点的树,每个节点有点权,编号为1的节点是树的根。
有m次操作:
操作1:给x加上val,然后给x的所有子节点加上-val,x的子节点的子节点加上-(-val),不断传递。
操作2:查询点x的点权。
思路:
该题是关于子树的问题,可以先将树转化为dfs序,变成序列问题再用线段树解决。
本题难点在于,每次下传val的时候,要取反。
我们设d[x]为x到根的奇偶性,0/1表示。
在修改x的点权时,在以x为根的子树中,所有与x深度奇偶性相同的点+val,所有与x深度奇偶性不同的点-val。
根据上述分析,我们考虑把奇数层和偶数层分开,建2棵树。
在修改x的时候,与x奇偶性相同的树[L,R]添加val,这样做是为了将[L,R]中与x奇偶性相同的点全部加上val
并且与x奇偶性不同的树[L,R]减少val,这样做是为了将[L,R]中与x奇偶性不同的点全部加上val
奇数树中,深度为偶数的位置是没用的,直接忽略,偶数树同理。
1 |
|
三、欧拉序

根据欧拉序,求
例题:树上LCA3
1 |
|
四、总结
- 倍增:无修改路径信息
- DFS序:待修改子树信息(转化为区间),修改路径信息不行的(需要树链剖分)
- 欧拉序:LCA
- Title: 倍增,DFS序,欧拉序
- Author: Nannan
- Created at : 2023-08-15 20:37:00
- Updated at : 2024-09-30 19:50:24
- Link: https://redefine.ohevan.com/2023/08/15/六、倍增,DFS序,欧拉序/
- License: This work is licensed under CC BY-NC-SA 4.0.