The sparse table holds the power-of-two aggregates and its queries return the range product full
This proof shows: correctness, termination.
Let (S,⊕) be a semigroup, so ⊕ is associative, and let n≥1. For 0≤a≤b≤n−1 write Π(a,b)=A[a]⊕⋯⊕A[b]. By associativity this does not depend on the brackets, and for a≤m<b,
Π(a,b)=Π(a,m)⊕Π(m+1,b).(1) Let K=⌊lgn⌋. 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+1 values, so every procedure ends.
Lemma 1 (the log table). After line L1, LG[m]=⌊lgm⌋ for 1≤m≤n.
Proof. By strong induction on m. LG[1]=0=⌊lg1⌋. For m≥2, let j=⌊lgm⌋≥1, so 2j≤m<2j+1. Then 2j−1≤m/2<2j, and since 2j−1 is an integer, also 2j−1≤⌊m/2⌋<2j. So ⌊lg⌊m/2⌋⌋=j−1. The loop sets LG[⌊m/2⌋] before LG[m], because ⌊m/2⌋<m, and by the hypothesis LG[m]=(j−1)+1=j. □
Lemma 2 (build). After BUILD, for each 0≤k≤K and 0≤i≤n−2k: ST[k][i]=Π(i,i+2k−1).
Proof. By induction on k. Line L2 gives ST[0][i]=A[i]=Π(i,i). Let 1≤k≤K and assume the claim for k−1. Line L3 runs to LG[n]=K by Lemma 1. For 0≤i≤n−2k, the cells read by line L5 exist: i≤n−2k−1, and i+2k−1≤n−2k−1 because i≤n−2k. By the hypothesis they are Π(i,i+2k−1−1) and Π(i+2k−1,i+2k−1), and by (1) with m=i+2k−1−1 their product is Π(i,i+2k−1). Row k is written only after row k−1 is complete, and row k−1 is not written again. □
Lemma 3 (fast query). Assume that ⊕ is also idempotent: x⊕x=x for each x∈S. For 0≤l≤r≤n−1, QUERY(l,r) returns Π(l,r).
Proof. Let L=r−l+1≤n. By Lemma 1, line L6 sets k=⌊lgL⌋, so 2k≤L<2k+1, and k≤K. Let a=r−2k+1 and b=l+2k−1. Then a≥l and b≤r, because 2k≤L. So both cells exist (0≤l≤n−2k and 0≤a≤n−2k), and by Lemma 2 line L7 returns Π(l,b)⊕Π(a,r). Also a≤b+1, because a−b−1=L−2k+1<0, so a≤b.
So l≤a≤b≤r. Write Π(l,b)=X⊕M and Π(a,r)=M⊕Y, where M=Π(a,b), X=Π(l,a−1) when l<a, and Y=Π(b+1,r) when b<r; by (1), each part that exists may be split off this way. If l<a and b<r, associativity and idempotence give
Π(l,b)⊕Π(a,r)=X⊕(M⊕M)⊕Y=X⊕M⊕Y=Π(l,r), the last step by (1) twice. If l=a, then Π(l,b)=M and the same computation without X gives M⊕M⊕Y=M⊕Y=Π(l,r), or M⊕M=M=Π(l,r) when also b=r. The case b=r with l<a is the mirror image. No step exchanges two factors, so commutativity is not used. □
Lemma 4 (query-any). For 0≤l≤r≤n−1, QUERY-ANY(l,r) returns Π(l,r), for any associative ⊕.
Proof. Write l0 for the first argument and l for the variable that line L10 moves. We use the invariant, at the start of the iteration for k in line L9:
(Q) l0≤l≤r+1, r−l+1<2k+1, and res is Π(l0,l−1), where res=e stands for the empty product when l=l0.
At the start, k=K, l=l0, and r−l+1≤n<2K+1, so (Q) holds. In the iteration for k: if l+2k−1≤r, then the cell ST[k][l] exists, since l+2k−1≤r≤n−1, and by Lemma 2 it is Π(l,l+2k−1). Line L10 makes res=Π(l0,l−1)⊕Π(l,l+2k−1)=Π(l0,l+2k−1) by (1), or just Π(l,l+2k−1) when res was empty, and moves l to l+2k. The new length r−l+1 is the old one minus 2k, which is less than 2k+1−2k=2k. If the test fails, then r−l+1<2k already. In both cases (Q) holds for k−1. After the iteration for k=0, (Q) gives r−l+1<1, so l=r+1, and res=Π(l0,r). This product is not empty, because l moved from l0≤r to r+1. □
Theorem. After BUILD on A[0…n−1], QUERY-ANY(l,r) returns A[l]⊕⋯⊕A[r] for every associative ⊕, and QUERY(l,r) returns the same value for every associative and idempotent ⊕, for all 0≤l≤r≤n−1.
Proof. Lemmas 2, 3 and 4, together with the termination shown at the start. ■