3.4.16 · D3Trees

Worked examples — Fenwick tree (Binary Indexed Tree) — prefix sums, O(log n) update and query

2,318 words11 min readBack to topic

This page is the stress test for the parent Fenwick tree note. We will not just re-solve one nice example — we will build a matrix of every kind of situation a Fenwick tree can be asked about, then work through examples until every cell of that matrix is covered.

Before we start, one reminder of the two moves, because every single example below is just these two moves on repeat:

Recall The only two operations (from the parent note)
  • Query (prefix sum ): start at , add , then set , repeat until . (walks DOWN toward 0)
  • Update (add to ): start at , add to , then set , repeat while . (walks UP toward )
  • = value of the lowest set bit. See Two's complement representation for why the negative-AND trick isolates that bit.

The scenario matrix

Here is every case class a Fenwick problem can throw at you. Each row is a distinct kind of trouble; the rightmost column names the worked example that nails it.

# Case class What could trip you Example
A Plain prefix query, positive values pick the right jump path Ex 1
B Negative values in the array sums can shrink, subtotals go negative Ex 2
C Point update, then re-query which cells to fix Ex 3
D Range sum subtract not Ex 4
E Boundary indices (, ) shortest and longest jump paths Ex 5
F Zero / degenerate (, empty range) loops that never run Ex 6
G Whole-array sum single cell if is a power of two Ex 7
H Real-world word problem (running bank balance) model it as point-update + prefix Ex 8
I Exam twist: recover a single element , or a slicker way Ex 9

Throughout, unless a new array is stated, we use this fixed test array (1-indexed, ):

The Fenwick cells for this array (built once) are:

Figure — Fenwick tree (Binary Indexed Tree) — prefix sums, O(log n) update and query

Example 1 — Cell A: a plain positive-flavoured query

Figure — Fenwick tree (Binary Indexed Tree) — prefix sums, O(log n) update and query

Example 2 — Cell B: negative values shrink the running total


Example 3 — Cell C: point update, then requery

Figure — Fenwick tree (Binary Indexed Tree) — prefix sums, O(log n) update and query

Example 4 — Cell D: range sum (the telescoping subtraction)


Example 5 — Cell E: boundary indices (shortest and longest paths)


Example 6 — Cell F: zero and degenerate inputs


Example 7 — Cell G: whole-array sum


Example 8 — Cell H: real-world word problem (running bank balance)


Example 9 — Cell I: exam twist — recover a single element


Recall

Recall Quick self-test across the matrix

Cell B: is a negative subtotal a bug? ::: No — Fenwick only adds; negative block sums are fine. Cell D: range formula? ::: query(r) - query(l-1). Cell F: what is query(0)? ::: 0 — the loop never runs; index 0 has no lowbit. Cell G: when is the whole sum a single cell? ::: When n is a power of two, tree[n] owns [1,n]. Cell I: recover a single a_j generically? ::: a_j = query(j) - query(j-1). Cell E: which query indices give length-1 paths? ::: i=1 and any power of two (single set bit).


Connections

  • Parent: Fenwick tree (Binary Indexed Tree) — prefix sums, O(log n) update and query (index 3.4.16)
  • Foundation for the range trick: Prefix sum array
  • Bit isolation behind : Two's complement representation, Binary representation of integers
  • A heavier alternative that also does these queries: Segment tree
  • Applications that reuse point-update + prefix: Inversion counting, Order statistics, Range update with difference array