Algorithm Search⌘K

Proofs: Disjoint sparse table

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

The disjoint sparse table returns the product of each range full

This proof shows: correctness, complexity.

Let (S,⋅)(S, \cdot) be a semigroup, A[0…n−1]A[0 \ldots n-1] over SS with n≥1n \ge 1, K=⌈lg⁡n⌉K = \lceil \lg n \rceil and N=2KN = 2^K. Write A[i…j]=A[i]⋅A[i+1]⋯A[j]A[i \ldots j] = A[i] \cdot A[i+1] \cdots A[j] for i≤ji \le j; by associativity it does not depend on the bracketing, and A[i…j]=A[i…k]⋅A[k+1…j]A[i \ldots j] = A[i \ldots k] \cdot A[k+1 \ldots j] for i≤k<ji \le k < j (the split law).

For 1≤h≤K1 \le h \le K and 0≤i<n0 \le i < n, let b=2h⌊i/2h⌋b = 2^h \lfloor i / 2^h \rfloor and m=b+2h−1m = b + 2^{h-1}. The table entry is T[h][i]=A[i…m−1]T[h][i] = A[i \ldots m-1] if i<mi < m and T[h][i]=A[m…i]T[h][i] = A[m \ldots i] if i≥mi \ge m.

Lemma 1 (build). BUILD sets every T[h][i]T[h][i] with i<ni < n to its definition.

Proof. Fix a block [b,b+2h)[b, b + 2^h) with middle mm. If m−1<nm - 1 < n, line L7 sets T[h][m−1]=A[m−1]=A[m−1…m−1]T[h][m-1] = A[m-1] = A[m-1 \ldots m-1]. For i=m−2i = m-2 down to bb, if T[h][i+1]=A[i+1…m−1]T[h][i+1] = A[i+1 \ldots m-1], then line L8 sets T[h][i]=A[i]⋅A[i+1…m−1]=A[i…m−1]T[h][i] = A[i] \cdot A[i+1 \ldots m-1] = A[i \ldots m-1]. So all of the left half is right when m−1<nm - 1 < n. If m−1≥nm - 1 \ge n, no query reads the left half of this block, since a query of level hh in this block has m≤r<nm \le r < n by Lemma 2, and these entries may hold anything. The right half is the same with T[h][i]=A[m…i−1]⋅A[i]=A[m…i]T[h][i] = A[m \ldots i-1] \cdot A[i] = A[m \ldots i]; it stops being written at i≥ni \ge n, and later entries of the block are never read. □\square

Lemma 2 (level). Let 0≤l<r<N0 \le l < r < N and let hh be the bit length of l⊕rl \oplus r. Then 1≤h≤K1 \le h \le K, and with b=2h⌊l/2h⌋b = 2^h \lfloor l / 2^h \rfloor and m=b+2h−1m = b + 2^{h-1}, we have b≤l<m≤r<b+2hb \le l < m \le r < b + 2^h.

Proof. l≠rl \ne r, so l⊕r≠0l \oplus r \ne 0 and h≥1h \ge 1; both are below 2K2^K, so h≤Kh \le K. The bits of ll and rr at positions ≥h\ge h are equal, so ⌊l/2h⌋=⌊r/2h⌋\lfloor l / 2^h \rfloor = \lfloor r / 2^h \rfloor and both lie in [b,b+2h)[b, b + 2^h). Bit h−1h - 1 is the highest bit where they differ, and l<rl < r, so it is 0 in ll and 1 in rr. Inside the block, bit h−1h - 1 is 0 exactly on [b,m)[b, m) and 1 exactly on [m,b+2h)[m, b + 2^h). □\square

Theorem. QUERY(l,r)=A[l…r](l, r) = A[l \ldots r] for 0≤l≤r<n0 \le l \le r < n, with at most one operation of SS.

Proof. If l=rl = r, line L1 returns A[l]A[l]. Otherwise, by Lemma 2 with the level hh of line L2, l<m≤rl < m \le r, so by Lemma 1, T[h][l]=A[l…m−1]T[h][l] = A[l \ldots m-1] and T[h][r]=A[m…r]T[h][r] = A[m \ldots r], both with indices below nn. By the split law, line L3 returns A[l…m−1]⋅A[m…r]=A[l…r]A[l \ldots m-1] \cdot A[m \ldots r] = A[l \ldots r]. □\square

Cost. Each level of BUILD performs at most one operation per position i<ni < n and 2h−12^{h-1} assignments without an operation per block, so at most nn operations per level and nKnK in total; the table has at most nKnK entries. A query is O(1)O(1) word operations plus one operation of SS.

Back to Disjoint sparse table