Algorithm Search⌘K

Proofs: Li Chao tree

These are the human proofs of Li Chao tree, at full length.

The Li Chao tree keeps a lowest line on every root path full

This proof shows: correctness, complexity.

The domain is the index range [0,C)[0, C) with C≥1C \ge 1; a line is a function f(i)=axi+bf(i) = a x_i + b of the index, and for two lines f,gf, g the difference f−gf - g is a linear function of xix_i, so it is monotone in ii. For a node vv over [lo,hi)[lo, hi) write P(i)P(i) for the path from the root to the leaf of ii.

Invariant (LC). (a) If a node holds no line, none of its descendants holds one. (b) For every inserted line ff and every index ii, some line gg stored on P(i)P(i) has g(i)≤f(i)g(i) \le f(i).

Lemma 1 (one step). Let gg and ff be the node line and the carried line at a node over [lo,hi)[lo, hi) after line L5, so g(mid)≤f(mid)g(mid) \le f(mid).

  1. If the walk stops at line L9, then g(i)≤f(i)g(i) \le f(i) for all i∈[lo,hi)i \in [lo, hi).
  2. If it goes left at line L7, then g(i)≤f(i)g(i) \le f(i) for all i∈[mid,hi)i \in [mid, hi).
  3. If it goes right at line L8, then g(i)≤f(i)g(i) \le f(i) for all i∈[lo,mid]i \in [lo, mid].

Proof. Let d=f−gd = f - g, monotone in ii. (1) d(lo)≥0d(lo) \ge 0 and d(hi−1)≥0d(hi - 1) \ge 0, so d≥0d \ge 0 between them. (2) d(lo)<0≤d(mid)d(lo) < 0 \le d(mid), so dd is non-decreasing, and d(i)≥d(mid)≥0d(i) \ge d(mid) \ge 0 for i≥midi \ge mid. (3) d(lo)≥0d(lo) \ge 0 and d(mid)≥0d(mid) \ge 0, so d≥0d \ge 0 on [lo,mid][lo, mid]. □\square

Lemma 2 (INSERT keeps (LC)). After INSERT(f0)(f_0), (LC) holds for the old lines and f0f_0.

Proof. (a) INSERT places a line only at the first empty node of its path, whose parent holds a line, and it never empties a node. For (b), consider the walk, with the carried line ctc_t at the tt-th node vtv_t. The lines that are "in flight" are those stored in the nodes and the carried line. We show the claim: after each step, for each line hh that is stored or carried at the start of the step and each index ii, either some stored line on P(i)P(i) is ≤h\le h at ii, or ii lies in the range of the next node and the carried line is ≤h\le h at ii.

At a swap on line L5 the two lines change places, so both are still stored or carried, at the same node. Then by Lemma 1, at the indices of [lo,hi)[lo, hi) that the walk leaves behind, the stored line gg is at most the carried line, and gg lies on P(i)P(i) for all of them. Indices outside [lo,hi)[lo, hi) are not affected: the carried line was carried into this node only for indices of its range. When the walk ends at line L3, the carried line is stored at a node whose range contains all its remaining indices. At line L6 the range has one index, which is midmid, where g≤fg \le f after line L5. Lines stored below the path are not moved. By induction over the steps, every line, old or new, is covered on every index. □\square

Theorem. QUERY(i)(i) returns min⁡ff(i)\min_f f(i) over all inserted lines, or +∞+\infty if there are none.

Proof. QUERY reads the stored lines on P(i)P(i) from the root down; by (a) it can stop at the first empty node, since none below holds a line. Every value it takes is the value of an inserted line, so the result is at least the minimum. By (b), for the line f∗f^* that attains the minimum at ii, some stored line on P(i)P(i) is at most f∗(i)f^*(i), so the result is at most the minimum. □\square

Cost. The tree over [0,C)[0, C) has at most ⌈lg⁡C⌉+1\lceil \lg C \rceil + 1 levels. INSERT and QUERY visit one node per level and evaluate at most four lines per node, so both take O(log⁡C)O(\log C) time. Each INSERT fills at most one empty node, so at most min⁡(n,2C−1)\min(n, 2C - 1) nodes hold lines.

Back to Li Chao tree