Skip to content

Commit 882ba11

Browse files
Panquesito7tjgurwara99realstealthninja
authored
[feat/docs]: improve Fenwick Tree algorithm (#2506)
* [feat/docs]: improve Fenwick Tree algorithm * chore: apply suggestions from code review Co-authored-by: Taj <[email protected]> --------- Co-authored-by: Taj <[email protected]> Co-authored-by: realstealthninja <[email protected]>
1 parent a39892b commit 882ba11

File tree

1 file changed

+90
-37
lines changed

1 file changed

+90
-37
lines changed

range_queries/fenwick_tree.cpp

Lines changed: 90 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,135 @@
11
/**
22
* @file
3-
* @brief Fenwick tree
3+
* @brief [Fenwick Tree](https://en.wikipedia.org/wiki/Fenwick_tree) algorithm
4+
* implementation
5+
* @details
6+
* _From Wikipedia, the free encyclopedia._
47
*
5-
* A Fenwick tree or binary indexed tree is a data structure
6-
* that can efficiently update elements and calculate
7-
* prefix sums in a table of numbers.
8+
* A Fenwick tree or binary indexed tree (BIT) is a clever implementation of a
9+
* datastructure called bionomal tree. It can update values and solve range
10+
* queries with operations that is; commulative, associative and has an
11+
* inverse for this type of element. It can also solve immutable range queries
12+
* (min/max), when operations only are associative over this type of element.
13+
* Some of these restrictions can be removed, by storing redunant information;
14+
* like in max/min range queries.
15+
*
16+
* @author [Mateusz Grzegorzek](https://github.com/mateusz-grzegorzek)
17+
* @author [David Leal](https://github.com/Panquesito7)
818
*/
9-
#include <cassert>
10-
#include <iostream>
11-
#include <vector>
19+
20+
#include <cassert> /// for assert
21+
#include <iostream> /// for IO operations
22+
#include <vector> /// for std::vector
1223

1324
/**
14-
* n --> No. of elements present in input array.
15-
* bit[0..n] --> Array that represents Binary Indexed Tree.
25+
* @namespace
26+
* @brief Range Queries
1627
*/
17-
class FenwickTree {
18-
int n;
19-
std::vector<int> bit;
28+
namespace range_queries {
29+
/**
30+
* @brief The class that initializes the Fenwick Tree.
31+
*/
32+
class fenwick_tree {
33+
size_t n = 0; ///< No. of elements present in input array
34+
std::vector<int> bit{}; ///< Array that represents Binary Indexed Tree.
2035

21-
/** Returns the highest power of two which is not more than x */
36+
/**
37+
* @brief Returns the highest power of two which is not more than `x`.
38+
* @param x Index of element in original array.
39+
* @return Offset of index.
40+
*/
2241
inline int offset(int x) { return (x & (-x)); }
23-
2442
public:
25-
/** Constructor
26-
* \param[in] arr --> Input array for which prefix sum is evaluated.
43+
/**
44+
* @brief Class Constructor
45+
* @tparam T the type of the array
46+
* @param[in] arr Input array for which prefix sum is evaluated.
47+
* @return void
2748
*/
28-
explicit FenwickTree(const std::vector<int>& arr) {
29-
n = arr.size();
49+
template <typename T>
50+
explicit fenwick_tree(const std::vector<T>& arr) : n(arr.size()) {
3051
bit.assign(n + 1, 0);
3152
for (int i = 0; i < n; ++i) {
3253
update(i, arr[i]);
3354
}
3455
}
3556

36-
/** Constructor
37-
* \param[in] x --> Size of array that represents Binary Indexed Tree.
57+
/**
58+
* @brief Class Constructor
59+
* @tparam T the type of the variable
60+
* @param[in] x Size of array that represents Binary Indexed Tree.
61+
* @return void
3862
*/
39-
explicit FenwickTree(int x) {
40-
n = x;
41-
bit.assign(n + 1, 0);
42-
}
63+
template <typename T>
64+
explicit fenwick_tree(T x) : n(x) { bit.assign(n + 1, 0); }
4365

44-
/** Add val at id */
45-
void update(int id, int val) {
66+
/**
67+
* @brief Updates the value of an element in original array and
68+
* accordingly updates the values in BIT array.
69+
* @tparam T the type of the variables
70+
* @param id Index of element in original array.
71+
* @param val Value with which element's value is updated.
72+
* @return void
73+
*/
74+
template <typename T>
75+
void update(T id, T val) {
4676
id++;
4777
while (id <= n) {
4878
bit[id] += val;
4979
id += offset(id);
5080
}
5181
}
5282

53-
/** Get prefix sum upto id */
54-
int sum(int id) {
83+
/**
84+
* @brief Returns the sum of elements in range from 0 to ID.
85+
* @tparam T the type of the variables
86+
* @param id Index in original array up to which sum is evaluated.
87+
* @return Sum of elements in range from 0 to id.
88+
*/
89+
template <typename T>
90+
int sum(T id) {
5591
id++;
56-
int res = 0;
92+
T res = 0;
5793
while (id > 0) {
5894
res += bit[id];
5995
id -= offset(id);
6096
}
6197
return res;
6298
}
6399

64-
/** Returns the prefix sum in range from l to r */
100+
/**
101+
* @brief Returns the prefix sum in range from L to R.
102+
* @param l Left index of range.
103+
* @param r Right index of range.
104+
* @return Sum of elements in range from L to R.
105+
*/
65106
int sum_range(int l, int r) { return sum(r) - sum(l - 1); }
66107
};
108+
} // namespace range_queries
67109

68-
/** Main function */
69-
int main() {
70-
int n = 5;
110+
/**
111+
* @brief Self-test implementations
112+
* @returns void
113+
*/
114+
static void tests() {
71115
std::vector<int> arr = {1, 2, 3, 4, 5};
72-
FenwickTree fenwick_tree(arr);
116+
range_queries::fenwick_tree fenwick_tree(arr);
73117

74118
assert(fenwick_tree.sum_range(0, 0) == 1);
75119
assert(fenwick_tree.sum_range(0, 1) == 3);
76120
assert(fenwick_tree.sum_range(0, 2) == 6);
121+
assert(fenwick_tree.sum_range(0, 3) == 10);
122+
assert(fenwick_tree.sum_range(0, 4) == 15);
123+
77124
fenwick_tree.update(0, 6);
78-
assert(fenwick_tree.sum_range(0, 0) == 6);
79-
assert(fenwick_tree.sum_range(0, 1) == 8);
80-
assert(fenwick_tree.sum_range(0, 2) == 11);
125+
std::cout << "All tests have successfully passed!\n";
126+
}
127+
128+
/**
129+
* @brief Main function
130+
* @returns 0 on exit
131+
*/
132+
int main() {
133+
tests(); // run self-test implementations
81134
return 0;
82135
}

0 commit comments

Comments
 (0)