🎉 All 30 days are live — the full DSA-30 course, from Big-O to System Design. See the roadmap →
Day 19 - Segment TreesFenwick Tree (BIT)

Fenwick Tree (Binary Indexed Tree)

A segment tree is general but bulky — 4n memory and a dozen lines per operation. When all you need is prefix sums with point updates, the Fenwick tree (a.k.a. Binary Indexed Tree, BIT) does the same job in n memory and about three lines per operation. It’s the structure competitive programmers reach for first because it’s so short to type.

What it computes

A BIT supports, over an array of length n:

  • update(i, delta) — add delta to arr[i], in O(log n).
  • prefixSum(i) — the sum of arr[1..i], in O(log n).

And a range sum sum(i, j) is just prefixSum(j) − prefixSum(i − 1). That’s it — point update + prefix query, and everything else is built from those two.

The core idea: each index covers a power-of-two block

The magic is in how the tree array bit[] is laid out. bit[i] stores the sum of a block of arr ending at index i, whose length is the lowest set bit of i. That “lowest set bit” is computed by the famous trick:

lowbit(i) = i & (-i)

Because of two’s-complement, i & -i isolates the lowest 1-bit of i. For example lowbit(12) = lowbit(1100₂) = 100₂ = 4, so bit[12] covers arr[9..12] (4 elements). lowbit(6) = lowbit(110₂) = 10₂ = 2, so bit[6] covers arr[5..6].

i & -i is the whole Fenwick tree in one expression. In two’s complement, -i is ~i + 1, which flips every bit above the lowest set bit and leaves the lowest set bit intact — so i & -i keeps exactly that lowest 1-bit. That value is both the size of the block index i is responsible for and the jump distance you add or subtract to walk the implicit tree. Everything else follows from it. (See Day 17 — Bit Manipulation for why i & -i isolates the low bit.)

The two loops

The beauty is that “walk the tree” is just repeatedly adding or subtracting lowbit:

  • update(i, delta) — move up, hitting every block that contains i: start at i, add lowbit(i) each step until past n.
  • prefixSum(i) — move down, accumulating disjoint blocks that tile [1..i]: start at i, subtract lowbit(i) each step until 0.

Both loops run at most log₂ n times because each step clears (or moves past) one bit.

⚠️

The Fenwick tree is 1-indexed, always. Index 0 is unusable because lowbit(0) = 0, so the update loop i += i & -i would never advance — an infinite loop. Shift your data to start at index 1 (update(i + 1, ...) if your array is 0-based). This off-by-one is the single most common BIT bug.

BIT vs segment tree — when to use which

Fenwick (BIT)Segment tree
Memoryn4n
Code length~3 lines/op~10 lines/op
Operationssum / prefix-sum (and invertible ops)any associative op (min, max, gcd, …)
Range updateneeds difference-array tricknatural with lazy propagation
Range min/maxno (not invertible)yes

The deciding factor: BIT only works for invertible aggregates (sum is invertible — you can subtract; min and max are not). If you need range min or max, you need a segment tree. If you need prefix sums, the BIT is shorter, smaller, and faster by a constant factor.

Range update, point query (the difference-array trick)

A BIT naturally does point update, range query. To flip it to range update, point query — “add v to all of [i, j], then read a single index” — store a difference array in the BIT: update(i, +v) and update(j + 1, −v). Then prefixSum(k) gives the total amount added at index k. Two BITs combined give range update + range query, but that’s rarely needed in interviews.

Quick check

What does the expression i & (-i) compute, and why is it central to a Fenwick tree?
Why must a Fenwick tree be 1-indexed?
You need range-MINIMUM queries with point updates. Can you use a Fenwick tree?

Next: Basic Questions — warm-ups for both structures, then the practice set.