Skip to content

Commit a55e362

Browse files
Arpan Mukherjeegithub-actionsPanquesito7kvedala
authored
Added Sparse Table for range query (#996)
* Added Sparse Table for range query * Fixed Lint Warnings * Fixed comments and Lint warnings * Fixed comments * Fixed comments and Lint warnings * Fixed comments and Lint warnings * Fixed variable reference Lint warnings * Added documentation for functions parameters and return statements * updating DIRECTORY.md * Added documentation * Applied namespace range_queries Co-authored-by: David Leal <[email protected]> * Updated wikipedia documentation link * Resolved comments * Fixed typo Co-authored-by: David Leal <[email protected]> * Resolved comments * Added tests * Cleaned up debugging statements * Resolved comments * Resolved Comments * Update sparse_table.cpp * Resolved comments Co-authored-by: Krishna Vedala <[email protected]> * Fixed comments * Update sparse_table.cpp Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: David Leal <[email protected]> Co-authored-by: Krishna Vedala <[email protected]>
1 parent 9565089 commit a55e362

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

DIRECTORY.md

+1
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@
213213
* [Heavy Light Decomposition](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/heavy_light_decomposition.cpp)
214214
* [Mo](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/mo.cpp)
215215
* [Segtree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/segtree.cpp)
216+
* [Sparse Table](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/sparse_table.cpp)
216217

217218
## Search
218219
* [Binary Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/binary_search.cpp)

range_queries/sparse_table.cpp

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/**
2+
* @file sparse_table.cpp
3+
* @brief Implementation of [Sparse Table](https://en.wikipedia.org/wiki/Range_minimum_query) data structure
4+
*
5+
* @details
6+
* Sparse Table is a data structure, that allows answering range queries.
7+
* It can answer most range queries in O(logn), but its true power is answering range minimum queries
8+
* or equivalent range maximum queries). For those queries it can compute the answer in O(1) time.
9+
*
10+
* * Running Time Complexity \n
11+
* * Build : O(NlogN) \n
12+
* * Range Query : O(1) \n
13+
*/
14+
15+
#include <vector>
16+
#include <cassert>
17+
#include <iostream>
18+
#include <algorithm>
19+
20+
/**
21+
* @namespace range_queries
22+
* @brief Range Queries algorithms
23+
*/
24+
namespace range_queries {
25+
/**
26+
* @namespace sparse_table
27+
* @brief Range queries using sparse-tables
28+
*/
29+
namespace sparse_table {
30+
/**
31+
* This function precomputes intial log table for further use.
32+
* @param n value of the size of the input array
33+
* @return corresponding vector of the log table
34+
*/
35+
template<typename T>
36+
std::vector<T> computeLogs(const std::vector<T>& A) {
37+
int n = A.size();
38+
std::vector<T> logs(n);
39+
logs[1] = 0;
40+
for (int i = 2 ; i < n ; i++) {
41+
logs[i] = logs[i/2] + 1;
42+
}
43+
return logs;
44+
}
45+
46+
/**
47+
* This functions builds the primary data structure sparse table
48+
* @param n value of the size of the input array
49+
* @param A array of the input integers
50+
* @param logs array of the log table
51+
* @return created sparse table data structure
52+
*/
53+
template<typename T>
54+
std::vector<std::vector<T> > buildTable(const std::vector<T>& A, const std::vector<T>& logs) {
55+
int n = A.size();
56+
std::vector<std::vector<T> > table(20, std::vector<T>(n+5, 0));
57+
int curLen = 0;
58+
for (int i = 0 ; i <= logs[n] ; i++) {
59+
curLen = 1 << i;
60+
for (int j = 0 ; j + curLen < n ; j++) {
61+
if (curLen == 1) {
62+
table[i][j] = A[j];
63+
}
64+
else {
65+
table[i][j] = std::min(table[i-1][j], table[i-1][j + curLen/2]);
66+
}
67+
}
68+
}
69+
return table;
70+
}
71+
72+
/**
73+
* This function is the query function to get the range minimum value
74+
* @param beg beginning index of the query range
75+
* @param end ending index of the query range
76+
* @param logs array of the log table
77+
* @param table sparse table data structure for the input array
78+
* @return minimum value for the [beg, end] range for the input array
79+
*/
80+
template<typename T>
81+
int getMinimum(int beg, int end, const std::vector<T>& logs, const std::vector<std::vector<T> >& table) {
82+
int p = logs[end - beg + 1];
83+
int pLen = 1 << p;
84+
return std::min(table[p][beg], table[p][end - pLen + 1]);
85+
}
86+
}
87+
} // namespace range_queries
88+
89+
/**
90+
* Main function
91+
*/
92+
int main() {
93+
std::vector<int> A{1, 2, 0, 3, 9};
94+
std::vector<int> logs = range_queries::sparse_table::computeLogs(A);
95+
std::vector<std::vector<int> > table = range_queries::sparse_table::buildTable(A, logs);
96+
assert(range_queries::sparse_table::getMinimum(0, 0, logs, table) == 1);
97+
assert(range_queries::sparse_table::getMinimum(0, 4, logs, table) == 0);
98+
assert(range_queries::sparse_table::getMinimum(2, 4, logs, table) == 0);
99+
return 0;
100+
}
101+

0 commit comments

Comments
 (0)