All questions

Fenwick Tree (Binary Indexed Tree)

Premium

Fenwick Tree (Binary Indexed Tree)

A Fenwick tree — also called a Binary Indexed Tree, or BIT — is a compact array structure that answers prefix-sum queries and applies point updates in O(log n) time each. It solves the problem where a plain prefix-sum array makes queries instant but every update O(n), and a plain array makes updates instant but every query O(n); the Fenwick tree keeps both logarithmic, with far less code and memory than a segment tree for the sum case. It does this with one trick — the lowest set bit of an index, x & -x — which you will build up in the solution. Your fenwickTree(arr) factory takes a numeric array and returns an object with update, prefixSum, and rangeSum. See Fenwick tree for background.

Signature

function fenwickTree(arr: number[]): {
  update(i: number, delta: number): void;  // ADD delta to the element at index i
  prefixSum(i: number): number;            // sum of arr[0..i] inclusive
  rangeSum(l: number, r: number): number;  // sum of arr[l..r] inclusive
};

Examples

const ft = fenwickTree([1, 3, 5, 7, 9, 11]);
ft.prefixSum(0);   // 1    — just arr[0]
ft.prefixSum(2);   // 9    — 1 + 3 + 5
ft.rangeSum(1, 3); // 15   — 3 + 5 + 7
ft.rangeSum(0, 5); // 36   — the whole array
const ft = fenwickTree([1, 3, 5, 7, 9, 11]);
ft.update(2, 5);   // element 2 goes 5 -> 10 (adds 5, does not replace)
ft.prefixSum(2);   // 14   — 1 + 3 + 10
ft.rangeSum(0, 5); // 41   — now 36 + 5
ft.rangeSum(2, 2); // 10   — the updated element on its own

Notes

  • Caller indices are 0-basedarr is indexed from 0 the way you would expect. Internally the tree is 1-based, but that is your implementation detail; the caller never sees it.
  • update adds a delta — it does not set a value. To change arr[i] to some newVal, first work out the delta yourself: update(i, newVal - current).
  • Ranges are inclusiveprefixSum(i) includes index i; rangeSum(l, r) includes both l and r. Assume 0 <= l <= r <= n - 1.
  • Both queries and updates are O(log n) — a for loop that re-sums the array on every query, or rebuilds prefixes on every update, is the thing this structure exists to beat.
  • Do not mutate the input — read arr to build your tree, but leave the caller's array untouched.

FAQ

What is a Fenwick tree (Binary Indexed Tree) used for?
A Fenwick tree answers prefix-sum queries and applies point updates on an array in O(log n) time each, using a single array of n + 1 numbers. It is the go-to structure when values change between queries: a plain prefix-sum array gives O(1) queries but O(n) updates, and a plain array gives O(1) updates but O(n) queries, while a Fenwick tree keeps both logarithmic with far less code and memory than a segment tree for the sum case.
How does the lowest-set-bit trick (x & -x) work?
Because integers are stored in two's complement, -x is the bitwise inverse of x plus one, which flips every bit above the lowest set bit and leaves that bit aligned. ANDing x with -x therefore keeps only the lowest set bit, so x & -x is exactly the length of the block that tree index x is responsible for. update climbs by adding it (i += i & -i) and prefixSum descends by subtracting it (i -= i & -i).
Why is the tree 1-indexed when the caller uses 0-based indices?
The whole algorithm relies on x & -x to move between indices, and that trick breaks at 0 (0 & -0 is 0, so the loop would never advance or terminate). Storing the data at internal positions 1..n keeps every index nonzero, so the factory maps each caller index i to internal i + 1 and hides the offset entirely. Getting this mapping wrong is the classic off-by-one bug.

Unlock the solution & editor

  • Runnable editor + tests

    Solve in the browser with instant Jest feedback.

  • Detailed solutions

    Walkthroughs, edge cases, and complexity notes.

  • Multi-framework variants

    React, Vue, Vanilla, Angular — same question, different stacks.

Upgrade to Premium