如果 u u u不为 v v v的祖先并且 v v v不为 u u u的祖先,那么 u , v u,v u,v分别处于LCA( u , v u,v u,v)的两棵不同子树中。
前序遍历中,LCA( S S S)出现在所有 S S S中元素之前,后序遍历中LCA( S S S)则出现在所有 S S S中元素之后。
两点集并的最近公共祖先为两点集分别的最近公共祖先的最近公共祖先,即 L C A ( A ∩ B = L C A ( L C A ( A ) , L C A ( B ) ) ) LCA(A\cap B=LCA(LCA(A),LCA(B))) LCA(A∩B=LCA(LCA(A),LCA(B)))。
两点的最近公共祖先必定处在树上两点间的最短路上。
d ( u , v ) = h ( u ) + h ( v ) − 2 h ( L C A ( u , v ) ) d(u,v)=h(u)+h(v)-2h(LCA(u,v)) d(u,v)=h(u)+h(v)−2h(LCA(u,v)),其中 d d d是树上两点间的距离, h h h代表某点到树根的距离。
求法1:朴素算法(单词查询随机复杂度为 O ( log n ) O(\log n) O(logn),但是可以很容易卡到 O ( n ) O(n) O(n))
每次深度较大的向上跳(一步一步向上跳),知道两个点相遇。
求法2:倍增算法(最经典的LCA求法&朴素算法的倍增改进算法&预处理复杂度 O ( n log n ) O(n\log n) O(nlogn),单次查询复杂度 O ( log n ) O(\log n) O(logn))
设最开始 u , v u,v u,v两点深度相差为 y y y,先对 y y y进行二进制拆分,使两点深度一致。
题目1:查询树上两点的距离(性质5: d i s t [ u , v ] = d i s t [ u ] + d i s t [ v ] − 2 ∗ d i s t [ L C A ( u , v ) ] dist[u,v]=dist[u]+dist[v]-2*dist[LCA(u,v)] dist[u,v]=dist[u]+dist[v]−2∗dist[LCA(u,v)])