Algorithm Search⌘K

Proofs: LCA by binary lifting

These are the human proofs of LCA by binary lifting, at full length.

LCA by binary lifting returns the lowest common ancestor full

This proof shows: correctness, termination.

Let the tree have the vertices 0,…,n−10, \ldots, n-1 and the root rr. Write depth(x)depth(x) for the number of edges from rr to xx, p(x)p(x) for the parent of xx with p(r)=rp(r) = r, and pj(x)p^j(x) for pp applied jj times. For 0≤j≤depth(x)0 \le j \le depth(x), pj(x)p^j(x) is the ancestor of xx at distance jj; for j>depth(x)j > depth(x) it is rr. A vertex is an ancestor of itself. For vertices u,vu, v, lca(u,v)\mathrm{lca}(u, v) is the deepest common ancestor; it exists because rr is a common ancestor, and it is unique because the common ancestors of uu and vv all lie on the path from uu to rr, which has at most one vertex at each depth.

Lemma 1 (the table). After PREPROCESS, up[k][x]=p2k(x)up[k][x] = p^{2^k}(x) for each 0≤k<K0 \le k < K and each vertex xx.

Proof. Line L1 computes pp and depthdepth by BFS, which visits the vertices in order of distance from rr and sets the parent of each vertex to the vertex from which it is first reached, a vertex one level closer to rr. Line L3 gives up[0][x]=p(x)=p1(x)up[0][x] = p(x) = p^1(x). For k≥1k \ge 1, the loop of line L4 runs after level k−1k - 1 is complete, and by the induction hypothesis on kk, up[k][x]=p2k−1(p2k−1(x))=p2k(x)up[k][x] = p^{2^{k-1}}(p^{2^{k-1}}(x)) = p^{2^k}(x). □\square

Lemma 2 (lifting and the LCA). (a) If depth(u)≥depth(v)depth(u) \ge depth(v) and d=depth(u)−depth(v)d = depth(u) - depth(v), then lca(pd(u),v)=lca(u,v)\mathrm{lca}(p^d(u), v) = \mathrm{lca}(u, v). (b) If depth(u)=depth(v)depth(u) = depth(v), then for each j≥0j \ge 0, pj(u)=pj(v)p^j(u) = p^j(v) if and only if j≥depth(u)−depth(lca(u,v))j \ge depth(u) - depth(\mathrm{lca}(u, v)).

Proof. (a) The common ancestors of uu and vv have depth at most depth(v)depth(v), since each is an ancestor of vv. The ancestors of uu with depth at most depth(v)depth(v) are exactly the ancestors of pd(u)p^d(u). So uu and pd(u)p^d(u) have the same common ancestors with vv, and the same deepest one. (b) Let ℓ=lca(u,v)\ell = \mathrm{lca}(u, v) and t=depth(u)−depth(ℓ)t = depth(u) - depth(\ell). If j≥tj \ge t, both pj(u)p^j(u) and pj(v)p^j(v) are the ancestor of ℓ\ell at distance j−tj - t (or rr), so they are equal. If j<tj < t and pj(u)=pj(v)=xp^j(u) = p^j(v) = x, then xx is a common ancestor of uu and vv with depth(x)=depth(u)−j>depth(ℓ)depth(x) = depth(u) - j > depth(\ell), which contradicts the choice of ℓ\ell. □\square

Theorem. LCA(u,v)(u, v) returns lca(u,v)\mathrm{lca}(u, v), after O(K)O(K) steps.

Proof. Write ℓ=lca(u,v)\ell = \mathrm{lca}(u, v) for the original pair. After line L5, depth(u)≥depth(v)depth(u) \ge depth(v), and the pair is the same set, so ℓ\ell is unchanged.

Line L7. Let d=∑k∈B2kd = \sum_{k \in B} 2^k, where BB is the set of one bits of dd. Since d≤n−1<2Kd \le n - 1 < 2^K, B⊆{0,…,K−1}B \subseteq \{0, \ldots, K-1\}. By Lemma 1 each jump applies p2kp^{2^k}, and pa(pb(x))=pa+b(x)p^a(p^b(x)) = p^{a+b}(x), so after line L7, uu is pdp^d of the original uu. By Lemma 2(a), lca(u,v)=ℓ\mathrm{lca}(u, v) = \ell still, and now depth(u)=depth(v)depth(u) = depth(v).

Line L8. If u=vu = v, then uu is an ancestor of both original vertices at the depth of vv, and ℓ=lca(u,u)=u\ell = \mathrm{lca}(u, u) = u. The return is correct.

Lines L9 and L10. Now u≠vu \ne v and depth(u)=depth(v)depth(u) = depth(v). Let t=depth(u)−depth(ℓ)≥1t = depth(u) - depth(\ell) \ge 1, the distance from uu (and from vv) up to ℓ\ell, and let s=t−1≥0s = t - 1 \ge 0. We claim this invariant before the step for kk (for k=K−1,…,0k = K - 1, \ldots, 0), and after the step for k=0k = 0 with k=−1k = -1:

(I) u≠vu \ne v, depth(u)=depth(v)depth(u) = depth(v), lca(u,v)=ℓ\mathrm{lca}(u, v) = \ell, and s<2k+1s < 2^{k+1}.

Initialization. Before the step for k=K−1k = K - 1: the first three parts hold as shown. Also s<t≤depth(u)≤n−1<2Ks < t \le depth(u) \le n - 1 < 2^K.

Maintenance. Consider the step for kk. By Lemma 1, up[k][u]=p2k(u)up[k][u] = p^{2^k}(u) and up[k][v]=p2k(v)up[k][v] = p^{2^k}(v). By Lemma 2(b), these differ if and only if 2k<t2^k < t, that is 2k≤s2^k \le s.

If 2k≤s2^k \le s, line L10 sets u←p2k(u)u \gets p^{2^k}(u) and v←p2k(v)v \gets p^{2^k}(v). The new vertices differ, have equal depth, and are ancestors of the old ones below ℓ\ell (their distance to ℓ\ell is t−2k≥1t - 2^k \ge 1), so ℓ\ell is still their LCA by Lemma 2(b) applied to the old pair. The new ss is s−2k<2k+1−2k=2ks - 2^k < 2^{k+1} - 2^k = 2^k.

If 2k>s2^k > s, nothing changes, and s<2ks < 2^k already.

In both cases (I) holds with k−1k - 1 in place of kk.

Termination. The loop has exactly KK steps. After the step for k=0k = 0, (I) gives s<20=1s < 2^0 = 1, so s=0s = 0 and t=1t = 1: ℓ\ell is the parent of uu. Line L11 returns up[0][u]=p(u)=ℓup[0][u] = p(u) = \ell.

The number of steps is at most KK for line L7 and exactly KK for line L9, each of O(1)O(1) work. ■\blacksquare

Back to LCA by binary lifting