背景:有个题解需要介绍下这两者的性质,这里就顺便写了个总结了
核心:将树上问题转化成区间问题
欧拉序
欧拉序,有2*n或2*n-1个编号
dfs序,有n个编号
(2021年8月30日21点27分)upd:更新下面的第二种叫法为 欧拉环游序
欧拉序,我理解的有两种搞法(可能叫法有误,思想就是那个思想 )
- 进入节点记录,遍历完所有子节点后,出节点时,当前时间戳记录
- 进入节点记录,遍历子节点的时候,返回到本节点时记录
具体代码体现为
d
f
n
[
x
]
dfn[x]
dfn[x] 记录的是,
x
x
x节点的时间戳
s
a
[
y
]
sa[y]
sa[y]记录的是,时间戳为
y
y
y 的是哪个节点(也就是“谁”的意思)
第一种
void dfs(int u) {
sa[++tim] = u;
dfn[u] = tim;
for (son...) dfs(son);
sa[++tim] = u;
}
第二种
void dfs(int u) {
sa[++tim] = u;
dfn[u] = tim;
for (son...) {
dfs(son);
sa[++tim] = u;
}
}
这两者之间在处理树上问题时有不同的性质
例如有一棵树为
1 2
1 3
2 4
2 5
3 6
3 7
这里时间戳
d
f
n
dfn
dfn,指的是第一次进入节点的时间
第一种欧拉序可以为,2*N
欧拉序:1 2 4 4 5 5 2 3 6 6 7 7 3 1
时间戳:1 2 3 3 5 5 2 8 9 9 11 11 8 1
第二种为,2*N-1
欧拉序:1 2 4 2 5 2 1 3 6 3 7 3 1
时间戳:1 2 3 2 5 2 1 8 9 8 11 8 1
第一种的性质:
- 树上任意一点
x
x
x 的子树,在第一次出现
x
x
x和最后一个
x
x
x之间的所有出现的数,另外有个性质是这些出现次数和为偶数
举例:2 的子树,截取为2 4 4 5 5 2
中的4 4 5 5
,自行尝试一下其它的子树 - 树上任意两点
x
x
x和
y
y
y,路径上的点,为最后一个
x
x
x到第一个
y
y
y之间,出现奇数次的数。另外再加上lca(最近公共祖先)
举例:4 到 7 的树上路径
截取为4 5 5 2 3 6 6 7
,出现奇数次的数字4 2 3 7
,加上lca,树上路径的节点最终为4 2 1 3 7
- 通常将树上的问题,转化为区间问题求解,比如树上莫队,求解树链上不同数字的个数等等
第二种的性质:
- 树上任意一点的子树为,第一次出现
x
x
x 和 最后一个
x
x
x之间出现了的所有数,除去本节点的数
举例:2的子树,截取为2 4 2 5 2
,除去本节点为4 5
- 树上任意两点
x
x
x和
y
y
y,两点的
l
c
a
lca
lca,为第一次出现
x
x
x和第一次出现
y
y
y区间内,时间戳最小的那个值
举例:4到7的lca,截取为4 2 5 2 1 3 6 3 7
,注意,这里的时间戳,指的是第一次进入节点的时间
按照截取的数字,给出时间戳为
3 2 5 2 1 8 9 8 11
,时间戳最小的为1时刻,那么去找1时刻的那个点是谁,也就是欧拉序第1个位置的那个点,lca就是节点1 - 通常用作求 lca,结合ST表,在 O ( 1 ) O(1) O(1)时间内求解 l c a lca lca,适合在频繁求解 l c a lca lca的场景
dfs序
仅进入节点的时候记录
代码体现为
void dfs(int u) {
sa[++tim] = u;
dfn[u] = tim;
for (son...) dfs(son);
}
d f s序:1 2 4 5 3 6 7
时间戳:1 2 3 4 5 6 7
性质:
- 树上任意点
x
x
x 的子树(包含
x
x
x)为,当前第一次出现
x
x
x的位置到往后
s
z
[
x
]
sz[x]
sz[x] 个节点的区间,
s
z
[
x
]
sz[x]
sz[x]表示
d
f
s
dfs
dfs 时计算的 以
x
x
x为根 的树大小,假设
s
z
[
x
]
sz[x]
sz[x]包含了
x
x
x
举例:
2 2 2 的子树, s z [ 2 ] = 3 sz[2]=3 sz[2]=3
那么截取为,2 4 5
,如果要不包含 x x x,取 x x x往后,区间大小为 s z [ x ] − 1 sz[x]-1 sz[x]−1即可,也就是4 5
- 树上两点 x x x 和 y y y 的 l c a lca lca,需要配合链剖分,将树链变成一块块连续的序列,跳 t o p top top求解,这里不细说,但是却是比较重要常用的一部分,详细可以找找树链剖分的板子题康康
- 通常结合树剖等等进行维护树上链上的信息,比如,给某条链全部节点加上1,求解最大最小值等等