Skip to content

Commit 432e783

Browse files
authored
Merge pull request #7 from koba-e964/fenwick
Add FenwickTree
2 parents 235b2df + 4877090 commit 432e783

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

src/fenwicktree.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Reference: https://en.wikipedia.org/wiki/Fenwick_tree
2+
pub struct FenwickTree<T> {
3+
n: usize,
4+
ary: Vec<T>,
5+
e: T,
6+
}
7+
8+
impl<T: Clone + std::ops::AddAssign<T>> FenwickTree<T> {
9+
pub fn new(n: usize, e: T) -> Self {
10+
FenwickTree {
11+
n: n,
12+
ary: vec![e.clone(); n],
13+
e: e,
14+
}
15+
}
16+
pub fn accum(&self, mut idx: usize) -> T {
17+
let mut sum = self.e.clone();
18+
while idx > 0 {
19+
sum += self.ary[idx - 1].clone();
20+
idx &= idx - 1;
21+
}
22+
sum
23+
}
24+
/// performs data[idx] += val;
25+
pub fn add<U: Clone>(&mut self, mut idx: usize, val: U)
26+
where
27+
T: std::ops::AddAssign<U>,
28+
{
29+
let n = self.n;
30+
idx += 1;
31+
while idx <= n {
32+
self.ary[idx - 1] += val.clone();
33+
idx += idx & idx.wrapping_neg();
34+
}
35+
}
36+
/// Returns data[l] + ... + data[r - 1].
37+
pub fn sum(&self, l: usize, r: usize) -> T
38+
where
39+
T: std::ops::Sub<Output = T>,
40+
{
41+
self.accum(r) - self.accum(l)
42+
}
43+
}
44+
45+
#[cfg(test)]
46+
mod tests {
47+
use super::*;
48+
49+
#[test]
50+
fn fenwick_tree_works() {
51+
let mut bit = FenwickTree::new(5, 0i64);
52+
// [1, 2, 3, 4, 5]
53+
for i in 0..5 {
54+
bit.add(i, i as i64 + 1);
55+
}
56+
assert_eq!(bit.sum(0, 5), 15);
57+
assert_eq!(bit.sum(0, 4), 10);
58+
assert_eq!(bit.sum(1, 3), 5);
59+
}
60+
}

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ mod scc;
1010
mod segtree;
1111
mod string;
1212
mod twosat;
13+
14+
pub use fenwicktree::FenwickTree;

0 commit comments

Comments
 (0)