Fenwick Tree (Binary Indexed Tree)
Maintain prefix sums with O(log n) updates and queries using one tiny bit trick. Fenwick trees are the lightest dynamic range-query structure worth knowing.
Interactive visualization
Use the controls to connect the idea to concrete operations before diving into the full write-up.
Base array (1-indexed)
Fenwick array
Why Fenwick trees are useful
Prefix queries walk backward by removing the least-significant set bit. Updates walk forward by adding that same bit. That symmetry is the whole data structure.
Family
Range queries
Static and dynamic range aggregates via indexed trees, segment trees, and precomputed tables.
Builds on
1 topic
Read these first if you want the surrounding context.
Unlocks
1 next topic
Use these follow-ups when you want to apply the current idea in a richer setting.
Learning paths
2
This topic appears in curated progressions so you can keep moving without guessing the next step.
Choose this over that
Compare the main range-query structures
Fenwick trees sit in the middle: stronger than prefix sums, lighter than segment trees.
Prefix Sum
Choose this when: The array never changes and `O(1)` range sums are the whole goal.
Choose something else when: Point updates must stay sublinear.
Fenwick Tree (Binary Indexed Tree)
Choose this when: You want dynamic sums with a tiny implementation and good constants.
Choose something else when: The query operator is not naturally prefix-based.
Segment Tree
Choose this when: You need range minima/maxima, lazy propagation, or more general merge logic.
Choose something else when: All you need is sum-like behavior and minimal code.
Sparse Table
Choose this when: The data is static and idempotent range queries should be as fast as possible.
Choose something else when: Updates matter at all.
Problem
You need to support two operations on an array:
- point updates
- prefix or range sum queries
Prefix sums give queries but updates. A segment tree gives for both, but is heavier than necessary if all you need is prefix-style aggregation.
A Fenwick tree gives you the same asymptotic speed with a much smaller constant factor.
Intuition
The structure is just an array, but each bit[i] stores the sum of a chunk ending at i.
The chunk size is determined by the least significant set bit:
So bit[12] stores the sum of the last 4 elements ending at 12, because lowbit(12) = 4.
The magic is that these chunks partition any prefix into a handful of disjoint ranges.
Query
To compute prefixSum(i), keep jumping backward:
prefix_sum(i):
ans <- 0
while i > 0:
ans <- ans + bit[i]
i <- i - lowbit(i)
return ans
Each step removes one chunk from the end of the prefix.
Update
To add delta at index i, update every Fenwick cell whose chunk includes that index:
add(i, delta):
while i <= n:
bit[i] <- bit[i] + delta
i <- i + lowbit(i)
Query walks downward by stripping bits. Update walks upward by adding them back.
Range sums
Fenwick trees are naturally prefix-based, so range sums come from subtraction:
That means two prefix queries are enough for any range sum.
Why it works
Binary carries are doing the work for you.
i - lowbit(i)removes the last active block from a prefixi + lowbit(i)moves to the next larger block that also covers indexi
The structure is really about navigating those binary boundaries efficiently.
Fenwick vs segment tree vs sparse table
| Structure | Updates | Range query | Best for |
|---|---|---|---|
| Prefix sum | Static sums | ||
| Fenwick tree | Dynamic prefix/range sums | ||
| Segment tree | Richer merges and lazy propagation | ||
| Sparse table | none | Static idempotent queries |
Fenwick is the middle ground: much simpler than a segment tree, much more dynamic than a sparse table.
Complexity
| Operation | Time | Space |
|---|---|---|
| Add | ||
| Prefix sum | ||
| Range sum | ||
| Build by repeated adds |
Key takeaways
lowbit(i)is the whole structure: it tells you both the chunk size and where to jump next- Fenwick trees shine when you need dynamic sums but do not need the full generality of a segment tree
- Prefix and range queries are really the same problem; range sums are just two prefixes subtracted
- The implementation is compact enough that it is worth memorizing directly
- Euler tours often pair with Fenwick trees to turn subtree updates into array range operations
Practice problems
| Problem | Difficulty | Key idea |
|---|---|---|
| Range Sum Query - Mutable | 🟡 Medium | Classic Fenwick or segment tree problem |
| Count of Smaller Numbers After Self | 🔴 Hard | Coordinate compression plus Fenwick frequencies |
| Queries on a Permutation With Key | 🟡 Medium | Dynamic positions tracked with a BIT |
| Create Sorted Array through Instructions | 🔴 Hard | Prefix counts inside a compressed value domain |
Relation to other topics
- Segment tree is heavier but more flexible; Fenwick is the minimal dynamic range-sum structure
- Sparse table handles static range minima/maxima in , but cannot support updates
- Euler tour technique turns tree subtrees into contiguous intervals that a Fenwick tree can query
Build on these first
These topics supply the mental model or underlying structure that this page assumes.
What this enables
Once the current idea feels natural, these are the most useful next jumps.
Related directions
These topics live nearby conceptually, even if they are not direct prerequisites.
Tree Fundamentals
Understand roots, parents, children, depth, height, and traversal orders. A tree is a graph with enough structure to make many problems much simpler.
Euler Tour Technique
Flatten a rooted tree into an array so subtree problems become range problems. This is the bridge between trees and range-query structures.
Treap
Combine binary-search-tree ordering with heap priorities to get a balanced randomized tree with elegant split and merge operations.
Difference Array
Apply many range updates in O(1) each, then rebuild the final values with one prefix pass. Difference arrays are the update-side twin of prefix sums.
More from Range queries
Stay in the same family when you want parallel variations of the same mental model.
Prefix Sum
Precompute cumulative totals so any range sum becomes one subtraction. Prefix sums are the first serious range-query idea everyone should know.
Difference Array
Apply many range updates in O(1) each, then rebuild the final values with one prefix pass. Difference arrays are the update-side twin of prefix sums.
Li Chao Tree
Maintain dynamic line insertion and min/max queries by storing line candidates in a segment tree over x-values.
Mo's Algorithm
Reorder offline range queries so a moving window can answer them with small pointer adjustments instead of rebuilding from scratch.
Paths that include this topic
Follow one of these sequences if you want a guided next step instead of open-ended browsing.
Range-query toolkit
Start with static prefix tricks, then move into offline, persistent, dynamic, and precomputed range-query structures.
Rooted tree queries
Flatten subtrees, jump through ancestors, and break tree paths into array segments instead of climbing naively.
From the blog
Pair the atlas with recent writing from the rest of the site when you want a broader engineering perspective alongside the topic graph.