Fenwick Tree (Binary Indexed Tree)
A compact array-based structure that computes prefix sums and supports point updates in O(log n) with O(n) space — simpler and faster in practice than a segment tree for sum queries.
Syntax
class FenwickTree {
constructor(n) { this.tree = new Array(n + 1).fill(0); }
update(i, delta) { for (; i < this.tree.length; i += i & -i) this.tree[i] += delta; }
query(i) { let s = 0; for (; i > 0; i -= i & -i) s += this.tree[i]; return s; }
range(l, r) { return this.query(r) - this.query(l - 1); }
}
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
n | number | Yes | The size of the array (values are 1-indexed in a Fenwick tree). |
Returns
FenwickTree — A new Fenwick Tree instance initialized to all zeros.
Examples
class FenwickTree {
#t;
constructor(n) { this.#t = new Array(n + 1).fill(0); }
update(i, delta) { for (; i < this.#t.length; i += i & -i) this.#t[i] += delta; }
query(i) { let s = 0; for (; i > 0; i -= i & -i) s += this.#t[i]; return s; }
range(l, r) { return this.query(r) - this.query(l - 1); }
}
// Build from array
const arr = [1, 3, 5, 7, 9, 11];
const ft = new FenwickTree(arr.length);
arr.forEach((v, i) => ft.update(i + 1, v)); // 1-indexed
console.log(ft.query(4)); // prefix sum [1..4] = 1+3+5+7
console.log(ft.range(2, 5)); // range sum [2..5] = 3+5+7+9
ft.update(3, 4); // arr[3] += 4 (5 → 9)
console.log(ft.query(4)); // updated prefix sum
Output
16
24
20
// Count inversions in an array using a Fenwick tree
function countInversions(arr) {
const n = arr.length;
const sorted = [...new Set(arr)].sort((a, b) => a - b);
const rank = new Map(sorted.map((v, i) => [v, i + 1]));
const ft = new FenwickTree(n);
let inv = 0;
for (const v of arr) {
const r = rank.get(v);
inv += ft.query(n) - ft.query(r); // elements seen > v
ft.update(r, 1);
}
return inv;
}
console.log(countInversions([3, 1, 2, 4]));
Output
2
Notes
| Operation | Time | Space |
|-------------|---------|-------|
| Build | O(n) | O(n) |
| Point update | O(log n)| O(1) |
| Prefix query | O(log n)| O(1) |
| Range query | O(log n)| O(1) |
The key trick: `i & -i` isolates the lowest set bit of i,
giving the "responsibility range" of each index.
Fenwick trees are 1-indexed by convention. Compared to a segment
tree: simpler code, lower constant factor, but supports only
associative-invertible operations (sum, XOR — not min/max).