1
1
use std:: ops:: { Add , AddAssign } ;
2
2
3
- /// Fenwick Tree / Binary Indexed Tree
4
- /// Consider we have an array arr[0 . . . n-1]. We would like to
3
+ /// A Fenwick Tree (also known as a Binary Indexed Tree) is a data structure
4
+ /// that can efficiently update elements and calculate prefix sums in a table of numbers.
5
+ ///
6
+ /// If we have an array arr[0 . . . n-1]. We would like to:
5
7
/// 1. Compute the sum of the first i elements.
6
- /// 2. Modify the value of a specified element of the array arr[i] = x where 0 <= i <= n-1.Fenwick tree
8
+ /// 2. Modify the value of a specified element of the array arr[i] = x
9
+ /// where 0 <= i <= n-1.
10
+ ///
11
+ /// A simple solution is to run a loop from 0 to i-1 and calculate the sum of the elements.
12
+ /// To update a value, simply do arr[i] = x. The first operation takes O(n) time and the
13
+ /// second operation takes O(1) time. Another simple solution is to create an extra array and
14
+ /// store the sum of the first i elements at the i-th index in this new array. The sum of a given
15
+ /// range can be calculated in O(1) time, but the update operation takes O(n) time now. This works
16
+ /// well if the number of query operations is large and the number of update operations is small.
17
+ ///
18
+ /// The Fenwick tree provides a way to represent an array of numbers and perform two operations
19
+ /// in O(log n) time.
20
+ ///
21
+ /// The two operations are:
22
+ /// 1. Update: Given a number x and an index i, we need to add x to the i-th element.
23
+ /// 2. Query: Given an index i, we need to calculate the prefix sum of the first i elements.
24
+ ///
25
+ /// The Fenwick tree is represented as an array of n elements. The tree structure allows us to
26
+ /// perform efficient queries and updates. The tree is constructed in such a way that the value
27
+ /// of each node is the sum of the values of the nodes in its subtree.
28
+ ///
7
29
pub struct FenwickTree < T : Add + AddAssign + Copy + Default > {
8
30
data : Vec < T > ,
9
31
}
10
32
11
33
impl < T : Add < Output = T > + AddAssign + Copy + Default > FenwickTree < T > {
12
- /// construct a new FenwickTree with given length
34
+ /// Create a new FenwickTree with length `len`
35
+ ///
36
+ /// # Arguments
37
+ ///
38
+ /// * `len` - The length of the FenwickTree
39
+ ///
40
+ /// # Example
41
+ ///
42
+ /// ```rust
43
+ /// use rust_algorithms::data_structures::FenwickTree;
44
+ ///
45
+ /// let mut ft = FenwickTree::with_len(10);
46
+ /// ft.add(0, 1);
47
+ /// ft.add(1, 2);
48
+ ///
49
+ /// assert_eq!(ft.prefix_sum(0), 1);
50
+ /// assert_eq!(ft.prefix_sum(1), 3);
51
+ /// ```
13
52
pub fn with_len ( len : usize ) -> Self {
14
53
FenwickTree {
15
54
data : vec ! [ T :: default ( ) ; len + 1 ] ,
16
55
}
17
56
}
18
57
19
- /// add `val` to `idx`
58
+ /// Add `val` to the `i`-th element
59
+ ///
60
+ /// # Arguments
61
+ ///
62
+ /// * `i` - The index of the element to add `val` to
63
+ /// * `val` - The value to add to the `i`-th element
64
+ ///
65
+ /// # Example
66
+ ///
67
+ /// ```rust
68
+ /// use rust_algorithms::data_structures::FenwickTree;
69
+ ///
70
+ /// let mut ft = FenwickTree::with_len(10);
71
+ /// ft.add(0, 3);
72
+ /// ft.add(1, 2);
73
+ ///
74
+ /// assert_eq!(ft.prefix_sum(0), 3);
75
+ /// assert_eq!(ft.prefix_sum(1), 5);
76
+ /// ```
20
77
pub fn add ( & mut self , i : usize , val : T ) {
21
78
assert ! ( i < self . data. len( ) ) ;
79
+
22
80
let mut i = i + 1 ;
81
+
23
82
while i < self . data . len ( ) {
24
83
self . data [ i] += val;
25
84
i += lowbit ( i) ;
26
85
}
27
86
}
28
87
29
- /// get the sum of [0, i]
88
+ /// Get the prefix sum of the first `i` elements
89
+ ///
90
+ /// # Arguments
91
+ ///
92
+ /// * `i` - The index of the last element to calculate the prefix sum of
93
+ ///
94
+ /// # Example
95
+ ///
96
+ /// ```rust
97
+ /// use rust_algorithms::data_structures::FenwickTree;
98
+ ///
99
+ /// let mut ft = FenwickTree::with_len(10);
100
+ /// ft.add(0, 1);
101
+ /// ft.add(1, 2);
102
+ /// ft.add(2, 3);
103
+ /// ft.add(3, 4);
104
+ /// ft.add(4, 5);
105
+ /// ft.add(5, 6);
106
+ /// ft.add(6, 7);
107
+ /// ft.add(7, 8);
108
+ /// ft.add(8, 9);
109
+ /// ft.add(9, 10);
110
+ ///
111
+ /// assert_eq!(ft.prefix_sum(0), 1);
112
+ /// assert_eq!(ft.prefix_sum(1), 3);
113
+ /// assert_eq!(ft.prefix_sum(2), 6);
114
+ /// assert_eq!(ft.prefix_sum(3), 10);
115
+ /// assert_eq!(ft.prefix_sum(4), 15);
116
+ /// assert_eq!(ft.prefix_sum(5), 21);
117
+ /// assert_eq!(ft.prefix_sum(6), 28);
118
+ /// assert_eq!(ft.prefix_sum(7), 36);
119
+ /// assert_eq!(ft.prefix_sum(8), 45);
120
+ /// assert_eq!(ft.prefix_sum(9), 55);
121
+ /// ```
30
122
pub fn prefix_sum ( & self , i : usize ) -> T {
31
123
assert ! ( i < self . data. len( ) ) ;
124
+
32
125
let mut i = i + 1 ;
33
126
let mut res = T :: default ( ) ;
127
+
34
128
while i > 0 {
35
129
res += self . data [ i] ;
36
130
i -= lowbit ( i) ;
37
131
}
132
+
38
133
res
39
134
}
40
135
}
@@ -44,32 +139,3 @@ const fn lowbit(x: usize) -> usize {
44
139
let x = x as isize ;
45
140
( x & ( -x) ) as usize
46
141
}
47
-
48
- #[ cfg( test) ]
49
- mod tests {
50
- use super :: * ;
51
- #[ test]
52
- fn it_works ( ) {
53
- let mut ft = FenwickTree :: with_len ( 10 ) ;
54
- ft. add ( 0 , 1 ) ;
55
- ft. add ( 1 , 2 ) ;
56
- ft. add ( 2 , 3 ) ;
57
- ft. add ( 3 , 4 ) ;
58
- ft. add ( 4 , 5 ) ;
59
- ft. add ( 5 , 6 ) ;
60
- ft. add ( 6 , 7 ) ;
61
- ft. add ( 7 , 8 ) ;
62
- ft. add ( 8 , 9 ) ;
63
- ft. add ( 9 , 10 ) ;
64
- assert_eq ! ( ft. prefix_sum( 0 ) , 1 ) ;
65
- assert_eq ! ( ft. prefix_sum( 1 ) , 3 ) ;
66
- assert_eq ! ( ft. prefix_sum( 2 ) , 6 ) ;
67
- assert_eq ! ( ft. prefix_sum( 3 ) , 10 ) ;
68
- assert_eq ! ( ft. prefix_sum( 4 ) , 15 ) ;
69
- assert_eq ! ( ft. prefix_sum( 5 ) , 21 ) ;
70
- assert_eq ! ( ft. prefix_sum( 6 ) , 28 ) ;
71
- assert_eq ! ( ft. prefix_sum( 7 ) , 36 ) ;
72
- assert_eq ! ( ft. prefix_sum( 8 ) , 45 ) ;
73
- assert_eq ! ( ft. prefix_sum( 9 ) , 55 ) ;
74
- }
75
- }
0 commit comments