LCA算法的概念:

  • 已知一个树和树上的两个点,求这两个点的最近公共祖先的算法
  • 单次查询在最坏情况下的时间复杂度:O({log_{2}}^{n})

LCA算法的注意事项:

  • 初始化时循环中的d[u]有时容易写成d[i]

LCA算法的例题(难度由低到高):

LCA算法的适用范围:

  • 无向树上

关于LCA算法的总结:

  • 倍增原理:LCA算法利用了倍增的原理,也就是类似ST表、快速幂和后缀数组等数据结构/算法的原理.LCA的思路和ST表很想,LCA和st表的主要区别可能就是LCA在查询的过程中首先将两个点放到了同一深度,并同时向上跳,也就是查询过程的区别.
  • 二进制性质:通过二进制基础,我们可以知道:2^{n}=2^{0}+2^{1}+...+2^{n-1},再结合我们算法的运行过程,也就证明了树上任何一个点都是可以通过LCA到达的.
  • 预处理:LCA的预处理利用了类似DP的思想(递推和记忆化).在处理一个结点时,这个结点上方的所有结点一定已经被处理过了,那么这个结点的预处理也就是可行的.(具体的证明可以自己手写下,通过模拟很容易推得(感性理解))
  • 时间复杂度:查询的时间复杂度在上面已经说过了.而预处理的时间复杂度为O({nlog_{2}}^{n})
  • 二分查找:LCA的过程类似二分查找的过程.二分查找是在一个区间内不断缩小区间,而LCA也是可以抽象为类似的思想.LCA的过程可以视为从一个接近无穷大的区间(实际情况中,区间长度只要大于实际要求的最大区间即可),然后不断二分(因为不是真正的无穷大区间,所以在O({log_{2}}^{n})的时间复杂度内的跳跃和预处理(这里的预处理指两个点移动到同一深度)是可以接受的).