Fenwick Tree Pattern
A Fenwick Tree, also known as a Binary Indexed Tree (BIT), is a compact array structure that supports prefix-sum queries and point updates in O(log n) using only n+1 slots of memory. It is the minimal, fastest answer to the canonical mutable-prefix-sum problem and is preferred over a segment tree whenever the aggregate is sum or xor and lazy range updates are not required.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Complexity
- Time
- O(log n) per query, O(log n) per update, O(n log n) build (or O(n) with linear-time variant)
- Space
- O(n)
When to use Fenwick Tree
- You need prefix sums (or range sums via subtraction) over an array that supports point updates.
- A pure prefix-sum array would force you to recompute O(n) entries on every mutation.
- The aggregate is invertible — sum, xor, or count — so range(l, r) = prefix(r) - prefix(l - 1).
- Memory is tight and the 4n footprint of a segment tree is undesirable.
- You are counting inversions, smaller-elements-to-the-right, or running rank queries on a compressed coordinate space.
Template
class FenwickTree {
constructor(size) {
this.n = size;
this.tree = new Array(size + 1).fill(0);
}
update(index, delta) {
let i = index + 1;
while (i <= this.n) {
this.tree[i] += delta;
i += i & -i;
}
}
prefixSum(index) {
let i = index + 1;
let sum = 0;
while (i > 0) {
sum += this.tree[i];
i -= i & -i;
}
return sum;
}
rangeSum(left, right) {
if (left === 0) return this.prefixSum(right);
return this.prefixSum(right) - this.prefixSum(left - 1);
}
static fromArray(nums) {
const bit = new FenwickTree(nums.length);
for (let i = 0; i < nums.length; i++) {
bit.tree[i + 1] += nums[i];
const parent = (i + 1) + ((i + 1) & -(i + 1));
if (parent <= nums.length) bit.tree[parent] += bit.tree[i + 1];
}
return bit;
}
}Example LeetCode problems
| # | Problem | Difficulty | Frequency |
|---|---|---|---|
| 307 | Range Sum Query - Mutable | medium | foundational |
| 315 | Count of Smaller Numbers After Self | hard | company favorite |
| 493 | Reverse Pairs | hard | company favorite |
| 1649 | Create Sorted Array through Instructions | hard | frequently asked |
| 327 | Count of Range Sum | hard | less common |
| 1569 | Number of Ways to Reorder Array to Get Same BST | hard | less common |
| 1409 | Queries on a Permutation With Key | medium | frequently asked |
| 2736 | Maximum Sum Queries | hard | company favorite |
Common mistakes
- Mixing 0-indexed and 1-indexed conventions inside the tree, which makes the `i & -i` trick walk off the end or skip the root.
- Calling update(index, newValue) when the API actually takes a delta — you must compute delta = newValue - currentValue first, otherwise the tree drifts.
- Forgetting to size the array as n + 1 and indexing tree[0], which is reserved as a sentinel and must always remain zero.
- Using a Fenwick tree for range-min or range-max queries; the structure relies on invertibility and silently returns wrong answers for non-invertible aggregates.
- Building the tree with n separate update() calls when the linear-time bottom-up variant is available and trims a log factor off the construction.
Frequently asked questions
How does the `i & -i` trick work?
`i & -i` isolates the lowest set bit of i, which corresponds to the size of the range that node i is responsible for in the implicit binary tree. Adding this value moves to the parent in the update path; subtracting it moves to the next range in the prefix-sum path.
Can a Fenwick Tree do range updates?
Yes, with a difference-array trick: maintain two BITs, one for the additive delta and one for delta multiplied by the index. The combined query reconstructs the value at any index in O(log n), though for general range update + range query the segment tree with lazy propagation is more flexible.
Why is the Fenwick Tree faster than a Segment Tree in practice?
Both are O(log n) per operation, but the BIT does fewer memory accesses (one path of length log n vs two paths) and has a smaller constant factor. It also fits in n+1 slots versus 4n, which improves cache behavior on large inputs.
How do I use a Fenwick Tree to count inversions?
Compress the coordinates so values are in [1, n], then scan the array right-to-left. At each position, query the prefix sum strictly less than the current value (count of already-seen smaller values to the right), then point-update the current value by +1. The sum of those queries is the inversion count.
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
Practice these live with InterviewChamp.AI
Drill the Fenwick Tree pattern under real interview conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →