Proofs: Tarjan's offline LCA algorithm
These are the human proofs of Tarjan's offline LCA algorithm, at full length.
Tarjan's offline LCA algorithm answers every query correctly full
This proof shows: correctness, termination.
Let be a tree with the vertices , rooted at , and let be the parent of . Write for the subtree of , and when is an ancestor of (each vertex is an ancestor of itself). The algorithm is TARJAN-OFFLINE-LCA with the lines L1 to L11.
Lemma 1 (the search). The stack always holds the path from to its top vertex, with the parent of each entry below it. Each vertex is pushed exactly once and popped exactly once, and a vertex is popped at line L8 only after every vertex of has been popped.
Proof. Line L6 pushes a child of the top , so the path property holds after a push, and a pop removes the last vertex of the path. A vertex is pushed only from its parent, at most once per edge , because each neighbour of is taken once. The vertex is popped only when it has no neighbour left to take, that is, after each child was pushed and, since lies above on the stack, popped again. By induction on the height of , every vertex of was popped before . Each vertex is pushed: by induction on the depth, a child of is taken before is popped.
Termination. Each iteration of line L4 either pushes a vertex or pops one. By Lemma 1 there are pushes and pops, so the loop stops after iterations.
Call a vertex open when it is on , and done when it has been popped. For a done vertex , let be the lowest open ancestor of , if one exists.
Lemma 2 (the invariant). At the start of each iteration of line L4, and also during line L9 for a vertex , the following hold.
(a) For each open vertex , the set of is together with the subtrees of the children of that are done.
(b) For each done vertex with an open ancestor, the set of is the set of , and its label is .
During line L9 for , the vertex is done but not yet merged, and (a) holds for as if it were open: the set of is , with the label .
Proof. At the start every set is a single vertex with its own label, and no vertex is done, so (a) and (b) hold. A push of changes no set, and has no done child yet, so its set fits (a).
Consider the pop of with parent . Just before it, by Lemma 1 all children of are done, so by (a) the set of is , and its label is : by (b) for a done , because is open and every vertex between and is done. This is the claim during line L9.
At line L10, UNION joins the set of , which by (a) is and the subtrees of the done children of , with . The child is now done, so the new set is what (a) asks for . The label of the new set becomes . For each , now done, the lowest open ancestor is , since is no longer open and is. For each done in an older subtree of a child of , is unchanged. All other sets are unchanged, and the open status of no other vertex changes. So (a) and (b) hold after the pop. If , line L10 does nothing and no open vertex is left.
Lemma 3 (the answer). Let line L9 run for , and let be done. Then .
Proof. At this moment the open vertices are the proper ancestors of , and itself counts as open for its set, as Lemma 2 says. If , then , and the set of is with the label .
Otherwise . The root is an ancestor of and is open, so exists, and by Lemma 2(b) the label of the set of is , the lowest vertex of the path from to that is an ancestor of . Every vertex of this path is an ancestor of . So is a common ancestor of and . Every common ancestor of and that is not lies on the path from to , and is not a common ancestor because . So is the lowest common ancestor.
Theorem. TARJAN-OFFLINE-LCA stops, and for each query it returns in .
Proof. It stops by the termination argument. By line L2, the query is stored at and at . Each vertex is popped once (Lemma 1). If , then when is popped, line L8 marks done before line L9, and Lemma 3 with gives . If , let be the one popped second. At the pop of , is not done, so line L9 writes nothing for there; at the pop of , is done, and Lemma 3 gives . No later step writes , since both entries of the query are read only at these two pops.