Files
C-Plus-Plus/range_queries/sparse_table_range_queries.cpp
realstealthninja 0d766b0f8a feat: update to CXX standard 17 and add CMakeLists file to directories without them (#2746)
* chore: add cache and build comment to git ignore

* fix: add cmakelists to dynamic programming

* fix: add cmakelists to greedy_algorithms

* fix: add cmakelists to operations_on_datastructures

* fix: add cmakelists to range_queries

* fix: add `dynamic_programmin`, `greedy_algorithms`, `range_queries` and `operations_on_datastructures` subdirectories to cmakelists.txt

* fix: init of transform_reduce in dynamic_programming

* fix: add an include for functional in catalan_numbers

* chore: bump CXX standard to 20

* revert: bump CXX standard to 20

* chore: bump c++ version to 17 and add justification

Arm supports c++ 17
Esp32 supports c++ 23
decision was made to be 17 because it seemed to offer the best combatability

* fix: compilation error in catalan numbers

* fix: add <set> header to longest increasing subsequence nlogn

* fix: add cmath & algorithm header to mo.cpp

* fix: remove register key word from fast integer

* fix: replace using namespace std with std::cin and std::cout

* docs: typo in c++17

* fix: memory leak in bellman_ford

* fix: typo in bellman_ford

* fix: typo in word_break

* fix: dynamic array in coin_change

* fix dynamic array in egg_dropping puzzle

* chore: remove unnecessary comment

* fix: add vla to be an error

* chore: add extra warnings

* fix: use add_compile options instead of set()

* fix: compile options are not strings

* fix: vla in floyd_warshall

* fix: vla in egg_dropping_puzzel

* fix: vla in coin_change

* fix: vla in edit_distance

* fix: vla in floyd_warshall

* feat: remove kadane and replace it with kadane2

* fix: vla in longest_common_subsequence

* fix: int overflow in floyd_warshall

* fix: vla in lisnlogn

* fix: use const vector& instead of array

* fix: use dynamic array instead of vla in knapsack

* fix: use of and in msvc is unsupported by default adding permissive flag fixes it

* test: make executables the tests themselves

* Revert "test: make executables the tests themselves"

This reverts commit 7a16c31c4e.

* fix: make dist constant in print

* fix: namespace issue in unbounded_0_1

* fix: include cstdint to fix compilation
2024-11-04 18:00:20 +05:30

106 lines
3.2 KiB
C++

/**
* @file sparse_table.cpp
* @brief Implementation of [Sparse
* Table](https://en.wikipedia.org/wiki/Range_minimum_query) data structure
*
* @details
* Sparse Table is a data structure, that allows answering range queries.
* It can answer most range queries in O(logn), but its true power is answering
* range minimum queries or equivalent range maximum queries). For those queries
* it can compute the answer in O(1) time.
*
* * Running Time Complexity \n
* * Build : O(NlogN) \n
* * Range Query : O(1) \n
*/
#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
/**
* @namespace range_queries
* @brief Range Queries algorithms
*/
namespace range_queries {
/**
* @namespace sparse_table
* @brief Range queries using sparse-tables
*/
namespace sparse_table {
/**
* This function precomputes intial log table for further use.
* @param n value of the size of the input array
* @return corresponding vector of the log table
*/
template <typename T>
std::vector<T> computeLogs(const std::vector<T>& A) {
int n = A.size();
std::vector<T> logs(n);
logs[1] = 0;
for (int i = 2; i < n; i++) {
logs[i] = logs[i / 2] + 1;
}
return logs;
}
/**
* This functions builds the primary data structure sparse table
* @param n value of the size of the input array
* @param A array of the input integers
* @param logs array of the log table
* @return created sparse table data structure
*/
template <typename T>
std::vector<std::vector<T> > buildTable(const std::vector<T>& A,
const std::vector<T>& logs) {
int n = A.size();
std::vector<std::vector<T> > table(20, std::vector<T>(n + 5, 0));
int curLen = 0;
for (int i = 0; i <= logs[n]; i++) {
curLen = 1 << i;
for (int j = 0; j + curLen < n; j++) {
if (curLen == 1) {
table[i][j] = A[j];
} else {
table[i][j] =
std::min(table[i - 1][j], table[i - 1][j + curLen / 2]);
}
}
}
return table;
}
/**
* This function is the query function to get the range minimum value
* @param beg beginning index of the query range
* @param end ending index of the query range
* @param logs array of the log table
* @param table sparse table data structure for the input array
* @return minimum value for the [beg, end] range for the input array
*/
template <typename T>
int getMinimum(int beg, int end, const std::vector<T>& logs,
const std::vector<std::vector<T> >& table) {
int p = logs[end - beg + 1];
int pLen = 1 << p;
return std::min(table[p][beg], table[p][end - pLen + 1]);
}
} // namespace sparse_table
} // namespace range_queries
/**
* Main function
*/
int main() {
std::vector<int> A{1, 2, 0, 3, 9};
std::vector<int> logs = range_queries::sparse_table::computeLogs(A);
std::vector<std::vector<int> > table =
range_queries::sparse_table::buildTable(A, logs);
assert(range_queries::sparse_table::getMinimum(0, 0, logs, table) == 1);
assert(range_queries::sparse_table::getMinimum(0, 4, logs, table) == 0);
assert(range_queries::sparse_table::getMinimum(2, 4, logs, table) == 0);
return 0;
}