UtilityToolsLab

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

About·Changelog·Privacy Policy·Terms of Service·Contact
HomeCompetitive ProgrammingSparse Table RMQ

Related Tools

Code FormatterMatrix GeneratorComplexity CalcBit VisualizerBitwise VisualizerBit ManipulationBitmask PlannerPrime FactorsMEX CalcInterval MergerMatrix RotationPBDS GeneratorSegment TreeGraph VisualizerDijkstra 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]
}