The sqrt tree stores the products it names and answers each query with at most two combines full
This proof shows: correctness, termination.
Let (S,⊕) be a semigroup and n≥1. For 0≤a≤b≤n−1 write Π(a,b)=A[a]⊕⋯⊕A[b]. By associativity, for a≤m<b,
Π(a,b)=Π(a,m)⊕Π(m+1,b).(1) For a layer j with block exponent bj, the block of an index i is βj(i)=⌊i/2bj⌋, and block p is the range [p2bj,min(n,(p+1)2bj)−1]. Write stj(p) and enj(p) for its first and last index.
Termination. Every loop of BUILD runs over a finite range that does not change in the loop, and the list of layers is finite because kj+1=⌈kj/2⌉<kj for kj≥2. QUERY has no loop.
Lemma 1 (the layer table). For each 1≤h<K there is exactly one layer j with bj≤h<kj, and line L2 sets LAYER[h] to it.
Proof. The intervals [bj,kj)=[kj+1,kj) are consecutive pieces of [kt,k0), where layer t is the last one. They are disjoint, and their union is [bt,K). The last layer has kt≥2 and kt+1=⌈kt/2⌉<2, so kt=2, since ⌈3/2⌉=2, and bt=1. If K<2, there is no layer and no h with 1≤h<K. □
Lemma 2 (prefixes and suffixes). After lines L3 and L4, PREj[i]=Π(stj(βj(i)),i) and SUFj[i]=Π(i,enj(βj(i))) for each layer j and each 0≤i≤n−1.
Proof. Fix a block [s,e]. By induction on i from s: PREj[s]=A[s]=Π(s,s), and PREj[i]=Π(s,i−1)⊕A[i]=Π(s,i) by (1). The suffixes are the mirror image, by induction on i downward from e, with A[i]⊕Π(i+1,e)=Π(i,e). The blocks of a layer are disjoint and cover [0,n−1], so every entry is set once. □
Lemma 3 (the between table). After lines L5 and L6, for blocks p≤q of the same segment of layer j, BTWj[p,q]=Π(stj(p),enj(q)).
Proof. By Lemma 2, SUFj[stj(p)]=Π(stj(p),enj(p)), the product of block p. By induction on q: BTWj[p,p] is this product, and BTWj[p,q]=Π(stj(p),enj(q−1))⊕Π(stj(q),enj(q))=Π(stj(p),enj(q)) by (1), since enj(q−1)+1=stj(q). The loop of line L6 stops at the last block of the segment that exists, so every entry it writes names a range inside [0,n−1]. □
Lemma 4 (the layer separates l and r). Let 0≤l<r≤n−1, let h≥1 be the highest bit of l xor r, and let j=LAYER[h]. Then p=βj(l) and q=βj(r) satisfy p<q, and p and q lie in the same segment of layer j.
Proof. Since r≤n−1<2K, the bits of l and r above K−1 are 0, so h<K and Lemma 1 applies: bj≤h<kj. The numbers l and r agree on all bits above h, so ⌊l/2h+1⌋=⌊r/2h+1⌋, and since h+1≤kj, also ⌊l/2kj⌋=⌊r/2kj⌋: the same segment. They differ at bit h≥bj, so ⌊l/2bj⌋=⌊r/2bj⌋, and l<r gives p<q. A block lies inside one segment, because 2bj divides 2kj. □
Lemma 5 (query). For 0≤l≤r≤n−1, QUERY(l,r) returns Π(l,r) and applies ⊕ at most twice.
Proof. If l=r, line L7 returns A[l]=Π(l,l) with no combine. If h=0, then l and r differ only in bit 0 and l<r, so r=l+1 and line L8 returns A[l]⊕A[r]=Π(l,l+1) with one combine. Otherwise h≥1, and by Lemma 4 the blocks p<q are in one segment of layer j. By Lemma 2, SUFj[l]=Π(l,enj(p)) and PREj[r]=Π(stj(q),r); both blocks are whole blocks of 2bj indices except possibly block q, which may be clipped at n−1≥r, so these ranges are as stated. If q=p+1, then enj(p)+1=stj(q), and line L10 returns Π(l,r) by (1), with one combine. If q>p+1, the blocks p+1 and q−1 lie in the same segment, between p and q, and by Lemma 3 BTWj[p+1,q−1]=Π(stj(p+1),enj(q−1)). The three ranges are consecutive and cover [l,r] in order, so line L11 returns Π(l,r) by (1) twice, with two combines. No step exchanges two factors, so commutativity is not used. □
Theorem. After BUILD on A[0…n−1] over any semigroup, QUERY(l,r) returns A[l]⊕⋯⊕A[r] with at most two applications of ⊕, for all 0≤l≤r≤n−1, and all procedures end.
Proof. Lemmas 1 to 5 and the termination argument. ■