树的最近公共祖先(LCA)

最近公共祖先简称 LCA(Lowest Common Ancestor)。两个节点的最近公共祖先,就是这两个点的公共祖先里面,离根最远的那个。

为了方便,我们记某点集 $S=v_1,v_2,\cdots,v_n$ 的最近公共祖先为 $\operatorname{LCA}(v_1,v_2,\cdots,v_n)$ 或 $\operatorname{LCA}(S)$。

性质

本节部分内容翻译自 wcipeg,并做过修改。

求法

模板题:Luogu P3379。

朴素求法

先让深度较大的点“跳”上去,知道两个点的深度相同,然后再让两个点共同向上“跳”,最后一定会找到两个点的 $\operatorname{LCA}$。

预处理只需要一次 $O(n)$ 遍历,极限数据(也就是链)可以把查询卡到 $O(n)$。

倍增求法

倍增求法类似于朴素求法,唯一的区别是:朴素算法在查询时一次跳 $1$ 层,而倍增算法使用倍增的方法,一次跳 $2^n,n \in \mathbb{N}$ 层。

因为需要一次跳 $2^n,n \in \mathbb{N}$ 层,预处理时就需要处理每一个节点的第 $2^n,n \in \mathbb{N}$ 个父亲,这里用 fa[i][j] 表示节点 $i$ 的第 $2^j$ 个父亲。预处理的时间复杂度为 $O(n \log n)$,单次查询的时间复杂度为 $O(\log n)$。

这种做法有以下的卡常技巧:

提交记录 备份

树链剖分

提交记录 备份

用欧拉序列转化为 RMQ 问题

提交记录 备份

用 DFS 序转化为 RMQ 问题

提交记录 备份

Tarjan 算法

动态树

标准 RMQ

例题:LCA 与树上点对的距离

名称 编号 备注 题解

例题:LCA 与简单路径之间的关系

名称 编号 备注 题解
LCA,树上差分
LCA,树上差分,去重
快递 ROI2016D2T3 提交记录 备份

例题:LCA 与查询树上点 $u$ 到点 $v$ 的答案

名称 编号 备注 题解
Painting GYM 104090J 将凸包转化为树上问题,凸包,二分答案 / LCT 提交记录 备份