mirror of
https://hub.njuu.cf/TheAlgorithms/C-Plus-Plus.git
synced 2023-10-11 13:05:55 +08:00
84 lines
2.3 KiB
C++
84 lines
2.3 KiB
C++
|
/**
|
||
|
* @file
|
||
|
* @brief
|
||
|
* [Prefix Sum
|
||
|
* Array](https://en.wikipedia.org/wiki/Prefix_sum) data structure
|
||
|
* implementation.
|
||
|
*
|
||
|
* @details
|
||
|
* Prefix Sum Array is a data structure, that allows answering sum in some range
|
||
|
* queries. It can answer most sum range queries in O(1), with a build time
|
||
|
* complexity of O(N). But it hasn't an update querie.
|
||
|
*
|
||
|
* * Running Time Complexity \n
|
||
|
* * Build : O(N) \n
|
||
|
* * Range Query : O(1) \n
|
||
|
* @author [Paulo Vitor Lima Borges](https://github.com/PauloVLB)
|
||
|
*/
|
||
|
|
||
|
#include <cassert> /// for assert
|
||
|
#include <iostream> /// for IO operations
|
||
|
#include <vector> /// for std::vector
|
||
|
|
||
|
/**
|
||
|
* @namespace range_queries
|
||
|
* @brief Range Queries algorithms
|
||
|
*/
|
||
|
namespace range_queries {
|
||
|
/**
|
||
|
* @namespace prefix_sum_array
|
||
|
* @brief Range sum queries using prefix-sum-array
|
||
|
*/
|
||
|
namespace prefix_sum_array {
|
||
|
|
||
|
std::vector<int64_t> PSA(1, 0);
|
||
|
|
||
|
/**
|
||
|
* @brief function that builds the PSA
|
||
|
* @param original_array original array of values
|
||
|
* @returns void
|
||
|
*/
|
||
|
void build(std::vector<int64_t> original_array) {
|
||
|
for (int i = 1; i <= static_cast<int>(original_array.size()); i++) {
|
||
|
PSA.push_back(PSA[i - 1] + original_array[i]);
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
* @brief query function
|
||
|
* @param beg begin of the interval to sum
|
||
|
* @param end end of the interval to sum
|
||
|
* @returns sum of the range [beg, end]
|
||
|
*/
|
||
|
int64_t query(int64_t beg, int64_t end) { return PSA[end] - PSA[beg - 1]; }
|
||
|
|
||
|
} // namespace prefix_sum_array
|
||
|
} // namespace range_queries
|
||
|
|
||
|
/**
|
||
|
* @brief Self-test implementations
|
||
|
* @returns void
|
||
|
*/
|
||
|
static void test() {
|
||
|
std::vector<int64_t> values{0, 123, 0, 2, -2, 5,
|
||
|
24, 0, 23, -1, -1}; // original array
|
||
|
|
||
|
range_queries::prefix_sum_array::build(values);
|
||
|
// queries are of the type: sum of the range [a, b] = psa[b] - psa[a-1]
|
||
|
|
||
|
assert(range_queries::prefix_sum_array::query(1, 10) ==
|
||
|
173); // sum of the entire array
|
||
|
assert(range_queries::prefix_sum_array::query(4, 6) ==
|
||
|
27); // the sum of the interval [4, 6]
|
||
|
assert(range_queries::prefix_sum_array::query(5, 9) ==
|
||
|
51); // the sum of the interval [5, 9]
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Main function
|
||
|
* @returns 0 on exit
|
||
|
*/
|
||
|
int main() {
|
||
|
test(); // run self-test implementations
|
||
|
return 0;
|
||
|
}
|