Algorithm Search⌘K

Proofs: Sparse table

These are the human proofs of Sparse table, at full length.

The sparse table holds the power-of-two aggregates and its queries return the range product full

This proof shows: correctness, termination.

Let (S,⊕)(S, \oplus) be a semigroup, so ⊕\oplus is associative, and let n≥1n \ge 1. For 0≤a≤b≤n−10 \le a \le b \le n - 1 write Π(a,b)=A[a]⊕⋯⊕A[b]\Pi(a, b) = A[a] \oplus \cdots \oplus A[b]. By associativity this does not depend on the brackets, and for a≤m<ba \le m < b,

Π(a,b)=Π(a,m)⊕Π(m+1,b).(1)\Pi(a, b) = \Pi(a, m) \oplus \Pi(m + 1, b). \tag{1}

Let K=⌊lg⁡n⌋K = \lfloor \lg n \rfloor. All loops of the procedures run over finite integer ranges that do not change inside the loop, and the loop of line L9 also runs over K+1K + 1 values, so every procedure ends.

Lemma 1 (the log table). After line L1, LG[m]=⌊lg⁡m⌋LG[m] = \lfloor \lg m \rfloor for 1≤m≤n1 \le m \le n.

Proof. By strong induction on mm. LG[1]=0=⌊lg⁡1⌋LG[1] = 0 = \lfloor \lg 1 \rfloor. For m≥2m \ge 2, let j=⌊lg⁡m⌋≥1j = \lfloor \lg m \rfloor \ge 1, so 2j≤m<2j+12^j \le m < 2^{j+1}. Then 2j−1≤m/2<2j2^{j-1} \le m/2 < 2^j, and since 2j−12^{j-1} is an integer, also 2j−1≤⌊m/2⌋<2j2^{j-1} \le \lfloor m/2 \rfloor < 2^j. So ⌊lg⁡⌊m/2⌋⌋=j−1\lfloor \lg \lfloor m/2 \rfloor \rfloor = j - 1. The loop sets LG[⌊m/2⌋]LG[\lfloor m/2 \rfloor] before LG[m]LG[m], because ⌊m/2⌋<m\lfloor m/2 \rfloor < m, and by the hypothesis LG[m]=(j−1)+1=jLG[m] = (j - 1) + 1 = j. □\square

Lemma 2 (build). After BUILD, for each 0≤k≤K0 \le k \le K and 0≤i≤n−2k0 \le i \le n - 2^k: ST[k][i]=Π(i,i+2k−1)ST[k][i] = \Pi(i, i + 2^k - 1).

Proof. By induction on kk. Line L2 gives ST[0][i]=A[i]=Π(i,i)ST[0][i] = A[i] = \Pi(i, i). Let 1≤k≤K1 \le k \le K and assume the claim for k−1k - 1. Line L3 runs to LG[n]=KLG[n] = K by Lemma 1. For 0≤i≤n−2k0 \le i \le n - 2^k, the cells read by line L5 exist: i≤n−2k−1i \le n - 2^{k-1}, and i+2k−1≤n−2k−1i + 2^{k-1} \le n - 2^{k-1} because i≤n−2ki \le n - 2^k. By the hypothesis they are Π(i,i+2k−1−1)\Pi(i, i + 2^{k-1} - 1) and Π(i+2k−1,i+2k−1)\Pi(i + 2^{k-1}, i + 2^k - 1), and by (1) with m=i+2k−1−1m = i + 2^{k-1} - 1 their product is Π(i,i+2k−1)\Pi(i, i + 2^k - 1). Row kk is written only after row k−1k - 1 is complete, and row k−1k - 1 is not written again. □\square

Lemma 3 (fast query). Assume that ⊕\oplus is also idempotent: x⊕x=xx \oplus x = x for each x∈Sx \in S. For 0≤l≤r≤n−10 \le l \le r \le n - 1, QUERY(l,r)(l, r) returns Π(l,r)\Pi(l, r).

Proof. Let L=r−l+1≤nL = r - l + 1 \le n. By Lemma 1, line L6 sets k=⌊lg⁡L⌋k = \lfloor \lg L \rfloor, so 2k≤L<2k+12^k \le L < 2^{k+1}, and k≤Kk \le K. Let a=r−2k+1a = r - 2^k + 1 and b=l+2k−1b = l + 2^k - 1. Then a≥la \ge l and b≤rb \le r, because 2k≤L2^k \le L. So both cells exist (0≤l≤n−2k0 \le l \le n - 2^k and 0≤a≤n−2k0 \le a \le n - 2^k), and by Lemma 2 line L7 returns Π(l,b)⊕Π(a,r)\Pi(l, b) \oplus \Pi(a, r). Also a≤b+1a \le b + 1, because a−b−1=L−2k+1<0a - b - 1 = L - 2^{k+1} < 0, so a≤ba \le b.

So l≤a≤b≤rl \le a \le b \le r. Write Π(l,b)=X⊕M\Pi(l, b) = X \oplus M and Π(a,r)=M⊕Y\Pi(a, r) = M \oplus Y, where M=Π(a,b)M = \Pi(a, b), X=Π(l,a−1)X = \Pi(l, a - 1) when l<al < a, and Y=Π(b+1,r)Y = \Pi(b + 1, r) when b<rb < r; by (1), each part that exists may be split off this way. If l<al < a and b<rb < r, associativity and idempotence give

Π(l,b)⊕Π(a,r)=X⊕(M⊕M)⊕Y=X⊕M⊕Y=Π(l,r),\Pi(l, b) \oplus \Pi(a, r) = X \oplus (M \oplus M) \oplus Y = X \oplus M \oplus Y = \Pi(l, r),

the last step by (1) twice. If l=al = a, then Π(l,b)=M\Pi(l, b) = M and the same computation without XX gives M⊕M⊕Y=M⊕Y=Π(l,r)M \oplus M \oplus Y = M \oplus Y = \Pi(l, r), or M⊕M=M=Π(l,r)M \oplus M = M = \Pi(l, r) when also b=rb = r. The case b=rb = r with l<al < a is the mirror image. No step exchanges two factors, so commutativity is not used. □\square

Lemma 4 (query-any). For 0≤l≤r≤n−10 \le l \le r \le n - 1, QUERY-ANY(l,r)(l, r) returns Π(l,r)\Pi(l, r), for any associative ⊕\oplus.

Proof. Write l0l_0 for the first argument and ll for the variable that line L10 moves. We use the invariant, at the start of the iteration for kk in line L9:

(Q) l0≤l≤r+1l_0 \le l \le r + 1, r−l+1<2k+1r - l + 1 < 2^{k+1}, and resres is Π(l0,l−1)\Pi(l_0, l - 1), where res=eres = e stands for the empty product when l=l0l = l_0.

At the start, k=Kk = K, l=l0l = l_0, and r−l+1≤n<2K+1r - l + 1 \le n < 2^{K+1}, so (Q) holds. In the iteration for kk: if l+2k−1≤rl + 2^k - 1 \le r, then the cell ST[k][l]ST[k][l] exists, since l+2k−1≤r≤n−1l + 2^k - 1 \le r \le n - 1, and by Lemma 2 it is Π(l,l+2k−1)\Pi(l, l + 2^k - 1). Line L10 makes res=Π(l0,l−1)⊕Π(l,l+2k−1)=Π(l0,l+2k−1)res = \Pi(l_0, l - 1) \oplus \Pi(l, l + 2^k - 1) = \Pi(l_0, l + 2^k - 1) by (1), or just Π(l,l+2k−1)\Pi(l, l + 2^k - 1) when resres was empty, and moves ll to l+2kl + 2^k. The new length r−l+1r - l + 1 is the old one minus 2k2^k, which is less than 2k+1−2k=2k2^{k+1} - 2^k = 2^k. If the test fails, then r−l+1<2kr - l + 1 < 2^k already. In both cases (Q) holds for k−1k - 1. After the iteration for k=0k = 0, (Q) gives r−l+1<1r - l + 1 < 1, so l=r+1l = r + 1, and res=Π(l0,r)res = \Pi(l_0, r). This product is not empty, because ll moved from l0≤rl_0 \le r to r+1r + 1. □\square

Theorem. After BUILD on A[0…n−1]A[0 \ldots n - 1], QUERY-ANY(l,r)(l, r) returns A[l]⊕⋯⊕A[r]A[l] \oplus \cdots \oplus A[r] for every associative ⊕\oplus, and QUERY(l,r)(l, r) returns the same value for every associative and idempotent ⊕\oplus, for all 0≤l≤r≤n−10 \le l \le r \le n - 1.

Proof. Lemmas 2, 3 and 4, together with the termination shown at the start. ■\blacksquare

Back to Sparse table