Lesson 15 / 42

Fenwick Tree (BIT)

A compact array-based structure for prefix sums and point updates in O(log n), simpler than a segment tree.

The trick

A Binary Indexed Tree (Fenwick tree) stores partial sums at indices chosen by the lowest set bit of i. Index i is responsible for a range of size i & (-i). This lets both update and prefix-sum run in O(log n) using only a single array.

Update & prefix sum

update walks up adding i & -i; prefix_sum walks down subtracting it. A range sum is prefix_sum(r) - prefix_sum(l-1).

bit = [0] * (n + 1)

def update(i, delta):
    while i <= n:
        bit[i] += delta
        i += i & (-i)

def prefix_sum(i):
    s = 0
    while i > 0:
        s += bit[i]
        i -= i & (-i)
    return s

def range_sum(l, r):
    return prefix_sum(r) - prefix_sum(l - 1)

Output:

update(3, 5)
range_sum(1, 3)  # includes the +5 at index 3

Fenwick vs segment tree

Fenwick trees are shorter to code and use half the memory, but only naturally support prefix-reducible operations like sum/xor. Segment trees generalize to min/max/gcd and range updates — pick Fenwick for sums, segment tree for everything else.

Quick check

Pick the correct time complexity.

Quick check: A Fenwick tree's update and prefix-sum operations run in:

  • O(1)
  • O(log n)
  • O(n)
  • O(n log n)
Answer

O(log n) — Both walk up/down the index by flipping the lowest set bit, taking O(log n) steps.