mirror of
https://hub.njuu.cf/TheAlgorithms/C-Plus-Plus.git
synced 2023-10-11 13:05:55 +08:00
Merge branch 'master' into kruskals_documentation
This commit is contained in:
commit
bd50a5219c
@ -1,48 +1,78 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Fenwick tree
|
||||
* @brief [Fenwick Tree](https://en.wikipedia.org/wiki/Fenwick_tree) algorithm
|
||||
* implementation
|
||||
* @details
|
||||
* _From Wikipedia, the free encyclopedia._
|
||||
*
|
||||
* A Fenwick tree or binary indexed tree is a data structure
|
||||
* that can efficiently update elements and calculate
|
||||
* prefix sums in a table of numbers.
|
||||
* A Fenwick tree or binary indexed tree (BIT) is a clever implementation of a
|
||||
* datastructure called bionomal tree. It can update values and solve range
|
||||
* queries with operations that is; commulative, associative and has an
|
||||
* inverse for this type of element. It can also solve immutable range queries
|
||||
* (min/max), when operations only are associative over this type of element.
|
||||
* Some of these restrictions can be removed, by storing redunant information;
|
||||
* like in max/min range queries.
|
||||
*
|
||||
* @author [Mateusz Grzegorzek](https://github.com/mateusz-grzegorzek)
|
||||
* @author [David Leal](https://github.com/Panquesito7)
|
||||
*/
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include <cassert> /// for assert
|
||||
#include <iostream> /// for IO operations
|
||||
#include <vector> /// for std::vector
|
||||
|
||||
/**
|
||||
* n --> No. of elements present in input array.
|
||||
* bit[0..n] --> Array that represents Binary Indexed Tree.
|
||||
* @namespace
|
||||
* @brief Range Queries
|
||||
*/
|
||||
class FenwickTree {
|
||||
int n;
|
||||
std::vector<int> bit;
|
||||
namespace range_queries {
|
||||
/**
|
||||
* @brief The class that initializes the Fenwick Tree.
|
||||
*/
|
||||
class fenwick_tree {
|
||||
size_t n = 0; ///< No. of elements present in input array
|
||||
std::vector<int> bit{}; ///< Array that represents Binary Indexed Tree.
|
||||
|
||||
/** Returns the highest power of two which is not more than x */
|
||||
/**
|
||||
* @brief Returns the highest power of two which is not more than `x`.
|
||||
* @param x Index of element in original array.
|
||||
* @return Offset of index.
|
||||
*/
|
||||
inline int offset(int x) { return (x & (-x)); }
|
||||
|
||||
public:
|
||||
/** Constructor
|
||||
* \param[in] arr --> Input array for which prefix sum is evaluated.
|
||||
/**
|
||||
* @brief Class Constructor
|
||||
* @tparam T the type of the array
|
||||
* @param[in] arr Input array for which prefix sum is evaluated.
|
||||
* @return void
|
||||
*/
|
||||
explicit FenwickTree(const std::vector<int>& arr) {
|
||||
n = arr.size();
|
||||
template <typename T>
|
||||
explicit fenwick_tree(const std::vector<T>& arr) : n(arr.size()) {
|
||||
bit.assign(n + 1, 0);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
update(i, arr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Constructor
|
||||
* \param[in] x --> Size of array that represents Binary Indexed Tree.
|
||||
/**
|
||||
* @brief Class Constructor
|
||||
* @tparam T the type of the variable
|
||||
* @param[in] x Size of array that represents Binary Indexed Tree.
|
||||
* @return void
|
||||
*/
|
||||
explicit FenwickTree(int x) {
|
||||
n = x;
|
||||
bit.assign(n + 1, 0);
|
||||
}
|
||||
template <typename T>
|
||||
explicit fenwick_tree(T x) : n(x) { bit.assign(n + 1, 0); }
|
||||
|
||||
/** Add val at id */
|
||||
void update(int id, int val) {
|
||||
/**
|
||||
* @brief Updates the value of an element in original array and
|
||||
* accordingly updates the values in BIT array.
|
||||
* @tparam T the type of the variables
|
||||
* @param id Index of element in original array.
|
||||
* @param val Value with which element's value is updated.
|
||||
* @return void
|
||||
*/
|
||||
template <typename T>
|
||||
void update(T id, T val) {
|
||||
id++;
|
||||
while (id <= n) {
|
||||
bit[id] += val;
|
||||
@ -50,10 +80,16 @@ class FenwickTree {
|
||||
}
|
||||
}
|
||||
|
||||
/** Get prefix sum upto id */
|
||||
int sum(int id) {
|
||||
/**
|
||||
* @brief Returns the sum of elements in range from 0 to ID.
|
||||
* @tparam T the type of the variables
|
||||
* @param id Index in original array up to which sum is evaluated.
|
||||
* @return Sum of elements in range from 0 to id.
|
||||
*/
|
||||
template <typename T>
|
||||
int sum(T id) {
|
||||
id++;
|
||||
int res = 0;
|
||||
T res = 0;
|
||||
while (id > 0) {
|
||||
res += bit[id];
|
||||
id -= offset(id);
|
||||
@ -61,22 +97,39 @@ class FenwickTree {
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Returns the prefix sum in range from l to r */
|
||||
/**
|
||||
* @brief Returns the prefix sum in range from L to R.
|
||||
* @param l Left index of range.
|
||||
* @param r Right index of range.
|
||||
* @return Sum of elements in range from L to R.
|
||||
*/
|
||||
int sum_range(int l, int r) { return sum(r) - sum(l - 1); }
|
||||
};
|
||||
} // namespace range_queries
|
||||
|
||||
/** Main function */
|
||||
int main() {
|
||||
int n = 5;
|
||||
/**
|
||||
* @brief Self-test implementations
|
||||
* @returns void
|
||||
*/
|
||||
static void tests() {
|
||||
std::vector<int> arr = {1, 2, 3, 4, 5};
|
||||
FenwickTree fenwick_tree(arr);
|
||||
range_queries::fenwick_tree fenwick_tree(arr);
|
||||
|
||||
assert(fenwick_tree.sum_range(0, 0) == 1);
|
||||
assert(fenwick_tree.sum_range(0, 1) == 3);
|
||||
assert(fenwick_tree.sum_range(0, 2) == 6);
|
||||
assert(fenwick_tree.sum_range(0, 3) == 10);
|
||||
assert(fenwick_tree.sum_range(0, 4) == 15);
|
||||
|
||||
fenwick_tree.update(0, 6);
|
||||
assert(fenwick_tree.sum_range(0, 0) == 6);
|
||||
assert(fenwick_tree.sum_range(0, 1) == 8);
|
||||
assert(fenwick_tree.sum_range(0, 2) == 11);
|
||||
std::cout << "All tests have successfully passed!\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main function
|
||||
* @returns 0 on exit
|
||||
*/
|
||||
int main() {
|
||||
tests(); // run self-test implementations
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user