Range Minimum Queries
Binary Indexed Trees
Fenwick Trees
Data Structures
Algorithm Optimization

Solving Range Minimum Queries using Binary Indexed Trees Fenwick Trees

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Range minimum query, or RMQ, asks for the minimum value in a subarray such as a[l..r]. The important technical point is that plain Fenwick trees are naturally designed for invertible prefix operations such as sums, not for arbitrary range minimum queries with fully general point updates. That is why segment trees or sparse tables are usually the standard answers instead.

Why Fenwick Trees Fit Sums Better Than Minimums

A Fenwick tree works beautifully for prefix sums because sums can be combined and subtracted:

  • prefix sum to r
  • minus prefix sum to l - 1
  • equals range sum on l..r

Minimum does not behave that way. Knowing min(0..r) and min(0..l-1) does not let you reconstruct min(l..r) by any simple inverse operation. That is the core reason RMQ is awkward for a standard binary indexed tree.

So if someone asks for a general dynamic RMQ structure, the honest answer is usually:

  • static RMQ: sparse table
  • dynamic point updates plus RMQ: segment tree
  • Fenwick tree: great for sums, counts, and similar prefix-friendly operations

What a Fenwick Tree Can Do

A Fenwick tree can support prefix minimum in special cases, especially when updates only decrease values. That is a narrower problem than full RMQ, but it is worth understanding because it explains where the confusion comes from.

Here is a Fenwick-like prefix-minimum structure in Python:

python
1class FenwickMin:
2    def __init__(self, n):
3        self.n = n
4        self.tree = [float("inf")] * (n + 1)
5
6    def update_decrease_only(self, i, value):
7        while i <= self.n:
8            self.tree[i] = min(self.tree[i], value)
9            i += i & -i
10
11    def prefix_min(self, i):
12        result = float("inf")
13        while i > 0:
14            result = min(result, self.tree[i])
15            i -= i & -i
16        return result
17
18fm = FenwickMin(5)
19values = [5, 3, 7, 2, 6]
20for index, value in enumerate(values, start=1):
21    fm.update_decrease_only(index, value)
22
23print(fm.prefix_min(4))

This works for prefix minimum under restricted update behavior. It does not give you full arbitrary min(l, r) queries with normal point reassignment semantics.

The Better Dynamic RMQ Answer: Segment Tree

For range minimum with arbitrary point updates, a segment tree is the standard data structure:

python
1class SegmentTree:
2    def __init__(self, data):
3        self.n = len(data)
4        self.tree = [float("inf")] * (4 * self.n)
5        self._build(data, 1, 0, self.n - 1)
6
7    def _build(self, data, node, left, right):
8        if left == right:
9            self.tree[node] = data[left]
10            return
11        mid = (left + right) // 2
12        self._build(data, node * 2, left, mid)
13        self._build(data, node * 2 + 1, mid + 1, right)
14        self.tree[node] = min(self.tree[node * 2], self.tree[node * 2 + 1])
15
16    def query(self, ql, qr, node=1, left=0, right=None):
17        if right is None:
18            right = self.n - 1
19        if ql <= left and right <= qr:
20            return self.tree[node]
21        if qr < left or right < ql:
22            return float("inf")
23        mid = (left + right) // 2
24        return min(
25            self.query(ql, qr, node * 2, left, mid),
26            self.query(ql, qr, node * 2 + 1, mid + 1, right),
27        )

This handles arbitrary range minimum queries cleanly and extends naturally to point updates.

The Best Static RMQ Answer: Sparse Table

If the array never changes, a sparse table is usually even better. It preprocesses the data so queries are answered in constant time after O(n log n) setup. That is the classic high-performance answer for static RMQ.

So the real design question is not "can I force a Fenwick tree to do RMQ." It is "what update and query pattern do I actually need."

Common Pitfalls

The most common mistake is assuming a Fenwick tree supports minimum queries the same way it supports sums. The missing inverse operation breaks that idea.

Another issue is implementing a prefix-minimum Fenwick structure and then assuming it solves arbitrary min(l, r) queries. It does not.

Developers also choose one data structure before clarifying whether the array is static or dynamically updated. That distinction determines the right tool.

Summary

  • Standard Fenwick trees are a natural fit for prefix sums, not for general RMQ.
  • Prefix minimum variants exist, but they solve a narrower problem than arbitrary range minimum with normal updates.
  • For dynamic RMQ with point updates, use a segment tree.
  • For static RMQ, use a sparse table.
  • The key reason minimum is harder than sum in a Fenwick tree is that minimum has no simple inverse operation.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.