Proofs: Offline RMQ in linear time with union-find (Arpa's trick)
These are the human proofs of Offline RMQ in linear time with union-find (Arpa's trick), at full length.
Arpa's trick returns the leftmost minimum of each range full
This proof shows: correctness, termination.
Write for the root of the tree of in the forest . Positions are compared as integers. We prove an invariant of the sweep and derive the answers from it.
Invariant (A). After line L7 of step , let the stack be , and put . Then:
- ;
- for , for the least with , and positions are their own roots;
- for each and each with , every has .
So part 3 says that is the unique leftmost minimum of : every earlier position of the interval has a strictly larger value.
We also use that every parent pointer goes to a larger position, , with equality only at roots. Line L6 sets with , and path compression sets with the root reached from , which is larger than when is not a root. So FIND climbs strictly increasing positions and stops after at most steps. This is the termination of each FIND; the sweep has steps, each position is pushed once and popped at most once, and there are finds, so the algorithm terminates.
Path compression keeps the roots. A FIND sets to for nodes on the path to that root, so each node keeps its root. So the statements of (A), which speak only of roots, the stack and the array, are not changed by the finds of lines L8 and L9. We can ignore compression below.
Base. Before step 0 the stack is empty and every position is a root. In step 0 nothing is popped and 0 is pushed. Then , , part 1 is empty, part 2 holds since , and part 3 holds for , because the range is empty.
Step. Assume (A) after step , with the stack . In step , the loop of lines L5 and L6 pops , the positions with , and stops at with , or when the stack runs out. By part 1, the popped positions are exactly the top ones with values larger than , because the values on the stack do not fall from bottom to top. Each popped , which is a root, gets the parent , which is a root. Line L7 pushes . The new stack is .
Part 1. by the stop condition, and the lower part is unchanged.
Part 2. For , the root of is the old one, with , which is still on the stack and is the least stack position . For , the old root was some popped with , which now has the parent , a root; so , the least stack position . For , . Positions after are untouched.
Part 3. For the intervals with , nothing changed. For the new last interval , take in it. If the claim is trivial. Otherwise lies in an old interval with . By part 3 for the old state, every has , because was popped. For in a later old interval with , the same argument applied to gives . So every has , which is part 3 for the new interval.
So (A) holds after step .
The answers. At line L9 of step , take a query . By part 2, , the least stack position , so . By part 3 with , every has . For , lies in some interval with , and by part 3 and part 1, . So is the minimum of , and no position before in the range reaches it. So is the leftmost minimum, which is the required answer.
Back to Offline RMQ in linear time with union-find (Arpa's trick)