Range Maximum Query Using Sparse Table – Theory, Preprocessing, and C++ Implementation
This article explains how to answer range maximum queries on a static array efficiently by preprocessing with a sparse table, achieving O(n log n) build time and O(1) query time, and provides a complete C++ implementation with state compression and interval decomposition.
The problem is to find the maximum value within any given interval of an array of N numbers, where a naive linear scan would take O(n) time per query.
Because the array does not change, one might consider precomputing results for all intervals, but that requires O(n²) time and space, which is impractical for large N.
The article introduces the sparse table technique, an offline preprocessing method that builds a table in O(n log n) time and answers each query in O(1) time. The table stores the maximum for intervals whose lengths are powers of two.
Define f[i][j] as the maximum value in the interval starting at index i with length 2^j. The recurrence relation is f[i][j] = max(f[i][j‑1], f[i + 2^{j‑1}][j‑1]), allowing the table to be filled by increasing j.
State compression is achieved by using the two dimensions (starting index i and exponent j) directly, reducing memory usage while preserving all needed information.
To answer a query for interval [a, b], compute j = ⌊log₂(b‑a+1)⌋. The answer is max(f[a][j], f[b‑2^j+1][j]), which combines two pre‑computed power‑of‑two intervals that together cover [a, b].
The article provides a complete C++ implementation. First, the arrays are declared: int high[50000][17], low[50000][17], n, q; Then the preprocessing function:
void solve()
{
for (int j = 1; (1 << j) <= n; ++j) {
for (int i = 0; i + (1 << j) <= n; ++i) {
high[i][j] = max(high[i][j-1], high[i + (1 << (j-1))][j-1]);
low[i][j] = min(low[i][j-1], low[i + (1 << (j-1))][j-1]);
}
}
}And the main function that reads input, builds the table, and processes queries:
int main()
{
cin >> n >> q;
for (int i = 0; i < n; ++i) {
cin >> high[i][0];
low[i][0] = high[i][0];
}
solve();
for (int i = 0; i < q; ++i) {
int a, b; cin >> a >> b; --a; --b;
int j = (int)(log(b - a + 1.0) / log(2.0));
int minHeight = min(low[a][j], low[b - (1 << j) + 1][j]);
int maxHeight = max(high[a][j], high[b - (1 << j) + 1][j]);
cout << maxHeight - minHeight << endl;
}
return 0;
}In conclusion, the sparse table provides a highly efficient solution for static range maximum (or minimum) queries, leveraging preprocessing, state compression, and dynamic programming; for mutable data, a segment tree or other online structure would be required.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
