The two-dimensional Fenwick tree keeps its block sums and returns rectangle sums full
This proof shows: correctness, termination.
We use 1-based table indices. For x≥1, g(x) is the lowest set bit of x and R(x)=(x−g(x),x]. Write M′[a][b]=M[a−1][b−1] for 1≤a≤n, 1≤b≤m. The invariant is
(F)F[i][j]=a∈R(i)∑b∈R(j)∑M′[a][b]for 1≤i≤n, 1≤j≤m. Lemma 1 (down chains). Let x≥0 and x0=x, xt+1=xt−g(xt) while xt>0. The chain reaches 0 after at most ⌊lgx⌋+1 steps when x≥1, and the ranges R(xt) over the nonzero xt are disjoint with union {1,…,x}.
Proof. Subtracting g(xt) clears the lowest set bit, so each step lowers the number of set bits by one, and x has at most ⌊lgx⌋+1 of them. The range R(xt) is (xt+1,xt]. These intervals are adjacent and descend from x to 0, so they are disjoint and their union is (0,x]. □
Lemma 2 (up chains). Let 1≤p≤N and p0=p, ps+1=ps+g(ps). For 1≤y≤N: p∈R(y) if and only if y=ps for some s. The chain has at most ⌊lgN⌋+1 terms that are at most N.
Proof. First, g(ps+1)>g(ps). Write ps=q⋅2k+1+2k with g(ps)=2k. Then ps+1=(q+1)2k+1, which is a multiple of 2k+1, so g(ps+1)=2k′ with k′≥k+1. So the chain is strictly increasing, and the exponent of g grows by at least 1 per step; since g(y)≤y≤N, at most ⌊lgN⌋+1 terms are at most N.
Every chain term covers p. Clearly p∈R(p0). We show R(ps)⊆R(ps+1). With the notation above, ps+1−g(ps+1)=(q+1)2k+1−2k′≤(q+1)2k+1−2k+1=q⋅2k+1=ps−g(ps), and ps<ps+1. So the interval (ps−g(ps),ps] lies inside (ps+1−g(ps+1),ps+1]. By induction p∈R(ps) for every s.
No other index covers p. Let p∈R(y), so y≥p=p0. Assume that y is not a chain term. The chain is strictly increasing and unbounded, so there is an s with ps<y<ps+1=ps+g(ps). Write y=ps+t with 0<t<g(ps). Since ps is a multiple of g(ps)>t, the lowest set bit of y is that of t, so g(y)=g(t)≤t. Then y−g(y)≥y−t=ps, so ps∈/R(y). But R(y) is an interval that ends at y>ps and holds p≤ps, so it holds ps. This is a contradiction. □
Lemma 3 (build). After BUILD, (F) holds.
Proof. Row pass. Fix a row i and write vj=M′[i][j] and Gj=F[i][j]. We show that after lines L2 and L3, Gj=∑b∈R(j)vb for all j. The loop pushes Gj into Gj+g(j) at step j. Call j′ a child of j when j′+g(j′)=j. Each child j′ of j is less than j, and Gj′ receives pushes only from its own children, which are less than j′, so Gj′ is final when it is pushed. So at the end, Gj=vj+∑j′ child of jGj′, and by induction on j it suffices that the ranges of the children of j split R(j)∖{j}=(j−g(j),j−1]. Let g(j)=2k and j=q⋅2k+1+2k. For 0≤t<k, the index j−2t has g(j−2t)=2t, since j is a multiple of 2k>2t, so it is a child of j. Conversely, let j′ be a child of j with g(j′)=2t. Adding 2t to j′ clears bit t with a carry, so j=j′+2t is a multiple of 2t+1. Then 2k=g(j)≥2t+1, so t<k and j′=j−2t. So the children are j−2t for 0≤t<k, with R(j−2t)=(j−2t+1,j−2t]. These intervals for t=0,…,k−1 are adjacent and cover (j−2k,j−1], as required.
Column pass. Lines L4 and L5 do the same push over i, with the whole row F[i][⋅] as the value, and vectors add entry by entry. By the same argument, after the pass row i is the sum of the rows i′ of the row pass with i′∈R(i), entry by entry. With the row pass this gives (F). □
Lemma 4 (add). If (F) holds before ADD(r,c,δ) with 0≤r<n and 0≤c<m, it holds after it for the matrix with M[r][c] increased by δ.
Proof. The right side of (F) for (i,j) grows by δ exactly when r+1∈R(i) and c+1∈R(j), and stays the same otherwise. By Lemma 2 with N=n and N=m, these are exactly the pairs with i on the up chain of r+1 and j on the up chain of c+1. Lines L6 to L12 visit exactly these pairs, each once, since the outer loop runs over the up chain of r+1 while i≤n, and line L8 restarts the inner loop over the up chain of c+1 for each i. □
Lemma 5 (prefix). If (F) holds, PREFIX(r,c) with 0≤r≤n and 0≤c≤m returns ∑a=1r∑b=1cM′[a][b].
Proof. The loops add F[i][j] for i on the down chain of r and j on the down chain of c, both without 0. By (F) this is the sum of M′ over the union of the blocks R(i)×R(j). By Lemma 1, the sets R(i) split {1,…,r} and the sets R(j) split {1,…,c}, so their products split {1,…,r}×{1,…,c}, and each cell of the corner is counted once. If r=0 or c=0, a loop does not run and the result is the empty sum 0. □
Lemma 6 (query). If (F) holds, QUERY(r1,c1,r2,c2) returns ∑r=r1r2∑c=c1c2M[r][c].
Proof. Let P(r,c) be the corner sum of Lemma 5. A cell (a,b) of M, 0-based, with a≤r2 and b≤c2 is counted in P(r2+1,c2+1), and is subtracted in P(r1,c2+1) when a<r1 and in P(r2+1,c1) when b<c1, and added back in P(r1,c1) when both hold. Its weight is (1−[a<r1])(1−[b<c1]), which is 1 inside the rectangle and 0 outside. Cells with a>r2 or b>c2 are in no term. The group is commutative, so the order of the terms does not matter. □
Termination. In BUILD all loops run over fixed finite ranges. In ADD, i≥1 and j≥1 at each step, so g(i),g(j)≥1 and the indices grow strictly up to the bounds n and m. In PREFIX, the indices drop strictly to 0 by Lemma 1. So every operation ends.
Theorem. After BUILD on M and any sequence of ADD calls, QUERY returns the sum of the current matrix over the given rectangle.
Proof. By Lemma 3, (F) holds after BUILD, and by Lemma 4 it holds after each ADD for the current matrix. By Lemma 6, QUERY then returns the rectangle sum, and every call ends by the termination argument. ■