Merge branch 'master' into kruskals_documentation

This commit is contained in:
David Leal 2023-07-21 12:17:06 -06:00 committed by GitHub
commit bd50a5219c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,48 +1,78 @@
/** /**
* @file * @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 * A Fenwick tree or binary indexed tree (BIT) is a clever implementation of a
* that can efficiently update elements and calculate * datastructure called bionomal tree. It can update values and solve range
* prefix sums in a table of numbers. * 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 <cassert> /// for assert
#include <vector> #include <iostream> /// for IO operations
#include <vector> /// for std::vector
/** /**
* n --> No. of elements present in input array. * @namespace
* bit[0..n] --> Array that represents Binary Indexed Tree. * @brief Range Queries
*/ */
class FenwickTree { namespace range_queries {
int n; /**
std::vector<int> bit; * @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 */ /**
inline int offset(int x) { return (x & (-x)); } * @brief Returns the highest power of two which is not more than `x`.
* @param x Index of element in original array.
public: * @return Offset of index.
/** Constructor
* \param[in] arr --> Input array for which prefix sum is evaluated.
*/ */
explicit FenwickTree(const std::vector<int>& arr) { inline int offset(int x) { return (x & (-x)); }
n = arr.size(); public:
/**
* @brief Class Constructor
* @tparam T the type of the array
* @param[in] arr Input array for which prefix sum is evaluated.
* @return void
*/
template <typename T>
explicit fenwick_tree(const std::vector<T>& arr) : n(arr.size()) {
bit.assign(n + 1, 0); bit.assign(n + 1, 0);
for (int i = 0; i < n; ++i) { for (int i = 0; i < n; ++i) {
update(i, arr[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) { template <typename T>
n = x; explicit fenwick_tree(T x) : n(x) { bit.assign(n + 1, 0); }
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++; id++;
while (id <= n) { while (id <= n) {
bit[id] += val; 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++; id++;
int res = 0; T res = 0;
while (id > 0) { while (id > 0) {
res += bit[id]; res += bit[id];
id -= offset(id); id -= offset(id);
@ -61,22 +97,39 @@ class FenwickTree {
return res; 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); } int sum_range(int l, int r) { return sum(r) - sum(l - 1); }
}; };
} // namespace range_queries
/** Main function */ /**
int main() { * @brief Self-test implementations
int n = 5; * @returns void
*/
static void tests() {
std::vector<int> arr = {1, 2, 3, 4, 5}; 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, 0) == 1);
assert(fenwick_tree.sum_range(0, 1) == 3); assert(fenwick_tree.sum_range(0, 1) == 3);
assert(fenwick_tree.sum_range(0, 2) == 6); 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); fenwick_tree.update(0, 6);
assert(fenwick_tree.sum_range(0, 0) == 6); std::cout << "All tests have successfully passed!\n";
assert(fenwick_tree.sum_range(0, 1) == 8); }
assert(fenwick_tree.sum_range(0, 2) == 11);
/**
* @brief Main function
* @returns 0 on exit
*/
int main() {
tests(); // run self-test implementations
return 0; return 0;
} }