对于有根树来说,LCA 指两点的最近公共祖先。求法较多,下面选取一些有特色的求法来讲解。
特点: O ( n ) O(n) O(n) 预处理,单次 O ( log n ) O(\log n) O(logn)。
首先对树进行轻重链剖分预处理。
在求两个点 u , v u,v u,v 的 LCA 时,分为以下两种情况:
由于重链数量为 O ( log n ) O(\log n) O(logn),所以单次复杂度为 O ( log n ) O(\log n) O(logn)。
特点: O ( n log n ) O(n\log n) O(nlogn) 预处理,单次 O ( log n ) O(\log n) O(logn),常数大,空间大,所以被上者吊打。
改进自逐步上移法。大致分为两个过程:
这两过程均可使用倍增加速。
原来是打算用欧拉序+RMQ 法的,但好像改用 dfs 序也挺好的,常数更小一点。
特点: O ( n log n ) O(n\log n) O(nlogn) 预处理,单次 O ( 1 ) O(1) O(1)。
首先我们对整棵树进行一次 dfs 得到 dfs 序。假如我们求的是
u
,
v
u,v
u,v 的 LCA (其中
d
f
n
u
<
d
f
n
v
dfn_u
我们综合 1 2,只要取出 [ d f n u + 1 , d f n v ] [dfn_u+1,dfn_v] [dfnu+1,dfnv] 中的深度最小点,再取其父亲即可。这个可以用 st 表处理。
还不会