UtilityToolsLab

© 2026 UtilityToolsLab. Built and maintained by the UtilityToolsLab Team.

Free eBooks·About·Changelog·Privacy Policy·Terms of Service·Report a bug
HomeCompetitive ProgrammingSparse Table RMQ

Related Tools

Code FormatterMatrix GeneratorComplexity CalcBit VisualizerBitmask PlannerPrime FactorsMEX CalcInterval MergerMatrix RotationPBDS GeneratorSegment TreeGraph VisualizerStress TesterModulo CalcConvex HullPath FinderOffline JudgeBig-O AnalyzerCombinatoricsDP Table BuilderExtended GCDSieve VisualizerBinary SearchSorting VisualizerUnion-Find DSU

Sparse Table (RMQ) Builder

Build a sparse table for O(1) range minimum queries. Visualise every level of the 2D precomputation table, run live queries, and copy the C++ template.

You Might Also Like

All Competitive Programming

Code Formatter

Format and beautify C++, Java, and Python code with consistent indentation. 100% client-side — no code leaves your browser.

Matrix Generator

Generate grid/matrix inputs for competitive programming. Random, zeros, identity, or sequential fill. Outputs in multiple formats.

Complexity Calc

Estimate Big-O operations and runtime for any N. Interactive reference table for all complexity classes from O(1) to O(N!).

Bit Visualizer

Toggle 32/64-bit grids. Click bits to flip them live and see decimal recalculate. Shows popcountll, clzll, ctzll, and MSB instantly.

Paste a list of integers and the Sparse Table Builder constructs the full 2D precomputation table that makes range-minimum queries answerable in O(1) time. The table has ⌊log₂ n⌋ + 1 levels; level k stores the minimum of every window of length 2k starting at each index. Once that table exists, any query over a[l..r] resolves by reading two cells, one anchored at l and one ending at r, and returning the smaller of the two because the windows overlap and a minimum is idempotent.

RMQ appears throughout competitive programming wherever you need the cheapest or most powerful element in a moving window: lowest common ancestor on a tree (after Euler-tour flattening), static range queries on a frequency table, the denominator in a sliding-window ratio problem, and anywhere a Segment Tree would work but its O(log n) query is a bottleneck. Sparse Table trades update capability for raw query speed. The structure is read-only after construction, which makes it the right call when the array is fixed and queries are dense.

Worked Example: Nine Values, One Table

The lead sample is 3 6 2 1 8 4 7 5 9, nine elements. Level 0 is the array itself. Level 1 stores window-of-2 minima: min(3,6)=3, min(6,2)=2, min(2,1)=1, and so on. Level 2 stores window-of-4 minima: min(3,6,2,1)=1 at index 0, min(6,2,1,8)=1 at index 1, etc. A query over [1,4] (values 6 2 1 8) uses k=2 (the largest power of 2 that fits 4 elements): sp[2][1] = min(6,2,1,8) = 1. Change the query to [0,2] and the tool returns 2, the minimum of 3 6 2.

How the Algorithm Builds and Queries

Building the table takes O(n log n) time and space. Querying any range [l, r] takes O(1): compute k = ⌊log₂(r − l + 1)⌋, then return min(sp[k][l], sp[k][r − 2k + 1]). The overlapping windows are valid because minimum is idempotent: counting an element twice does not change the result. Arrays up to 16 elements are accepted here; the generated C++ template scales to MAXN = 100001 and uses GCC's built-in __lg(x) for the floor-log₂ computation, which is a single instruction on x86.

When Not to Use a Sparse Table

  • Point updates invalidate the table. If the array changes after construction, the entire table must be rebuilt in O(n log n). Use a Segment Tree instead when updates and queries are interleaved; its O(log n) query costs more per call but tolerates modifications without a full rebuild.
  • Non-idempotent operations require a different structure.Sum and XOR are not idempotent (summing an element twice changes the result), so the overlapping-window trick is invalid. A Fenwick Tree or Segment Tree handles sum RMQ correctly in O(log n).
  • Very large n needs care with LOG sizing.The generated template declares LOG = ⌊log₂ n⌋ + 1 at compile time. If you resize MAXN without updating LOG, level k = LOG will silently read out of bounds. Always derive both constants from the same value.

a[0..8] — 9 elements

0
3
1
6
2
2
3
1
4
8
5
4
6
7
7
5
8
9

Sparse Table — sp[k][i] = min of a[i .. i + 2k − 1]

4 levels (k = 0 … 3) | Cells outside the valid window are shown as —

k \ i012345678window
k=036218475920 = 1
k=132114455—21 = 2
k=2111144———22 = 4
k=311———————23 = 8

Query Playground — O(1) Range Minimum Query

C++ Sparse Table Template

// Sparse Table (RMQ) — generated by UtilityToolsLab
// Array: {3, 6, 2, 1, 8, 4, 7, 5, 9}  |  N = 9
#include <bits/stdc++.h>
using namespace std;

const int MAXN = 100001;
const int LOG  = 4;  // floor(log2(n)) + 1

int sp[LOG][MAXN];

void build(int* arr, int n) {
    for (int i = 0; i < n; i++) sp[0][i] = arr[i];
    for (int k = 1; (1 << k) <= n; k++)
        for (int i = 0; i + (1 << k) - 1 < n; i++)
            sp[k][i] = min(sp[k-1][i],
                                   sp[k-1][i + (1 << (k-1))]);
}

// O(1) query: minimum of a[l..r] (0-indexed, inclusive)
int query(int l, int r) {
    int k = __lg(r - l + 1);   // __lg(x) = floor(log2(x)) in GCC
    return min(sp[k][l], sp[k][r - (1 << k) + 1]);
}

int main() {
    int arr[] = {3, 6, 2, 1, 8, 4, 7, 5, 9};
    int n = 9;
    build(arr, n);

    // Example queries
    cout << query(0, 8) << "\n";  // min of entire array
    cout << query(1, 3) << "\n";  // min of [1,3]
}