1#[derive(Debug, Clone)]
37pub struct FenwickTree {
38 tree: Vec<u32>,
40 n: usize,
42}
43
44impl FenwickTree {
45 pub fn new(n: usize) -> Self {
47 Self {
48 tree: vec![0u32; n + 1],
49 n,
50 }
51 }
52
53 pub fn from_values(values: &[u32]) -> Self {
57 let n = values.len();
58 let mut tree = vec![0u32; n + 1];
59
60 for (i, &v) in values.iter().enumerate() {
62 tree[i + 1] = v;
63 }
64
65 for i in 1..=n {
67 let parent = i + lowbit(i);
68 if parent <= n {
69 tree[parent] = tree[parent].wrapping_add(tree[i]);
70 }
71 }
72
73 Self { tree, n }
74 }
75
76 #[inline]
78 pub fn len(&self) -> usize {
79 self.n
80 }
81
82 #[inline]
84 pub fn is_empty(&self) -> bool {
85 self.n == 0
86 }
87
88 pub fn update(&mut self, i: usize, delta: i32) {
93 assert!(i < self.n, "index {i} out of bounds (n={})", self.n);
94 let mut idx = i + 1; while idx <= self.n {
96 if delta >= 0 {
97 self.tree[idx] = self.tree[idx].wrapping_add(delta as u32);
98 } else {
99 self.tree[idx] = self.tree[idx].wrapping_sub((-delta) as u32);
100 }
101 idx += lowbit(idx);
102 }
103 }
104
105 pub fn set(&mut self, i: usize, value: u32) {
107 let current = self.get(i);
108 let delta = value as i64 - current as i64;
109 self.update(i, delta as i32);
110 }
111
112 pub fn get(&self, i: usize) -> u32 {
116 if i == 0 {
117 self.prefix(0)
118 } else {
119 self.prefix(i).wrapping_sub(self.prefix(i - 1))
120 }
121 }
122
123 pub fn prefix(&self, i: usize) -> u32 {
128 assert!(i < self.n, "index {i} out of bounds (n={})", self.n);
129 let mut sum = 0u32;
130 let mut idx = i + 1; while idx > 0 {
132 sum = sum.wrapping_add(self.tree[idx]);
133 idx -= lowbit(idx);
134 }
135 sum
136 }
137
138 pub fn range(&self, left: usize, right: usize) -> u32 {
143 assert!(left <= right, "left {left} > right {right}");
144 if left == 0 {
145 self.prefix(right)
146 } else {
147 self.prefix(right).wrapping_sub(self.prefix(left - 1))
148 }
149 }
150
151 pub fn total(&self) -> u32 {
153 if self.n == 0 {
154 0
155 } else {
156 self.prefix(self.n - 1)
157 }
158 }
159
160 pub fn batch_update(&mut self, deltas: &[(usize, i32)]) {
165 for &(i, delta) in deltas {
166 self.update(i, delta);
167 }
168 }
169
170 pub fn rebuild(&mut self, values: &[u32]) {
177 assert_eq!(values.len(), self.n, "rebuild size mismatch");
178
179 self.tree.fill(0);
181
182 for (i, &v) in values.iter().enumerate() {
184 self.tree[i + 1] = v;
185 }
186
187 for i in 1..=self.n {
189 let parent = i + lowbit(i);
190 if parent <= self.n {
191 self.tree[parent] = self.tree[parent].wrapping_add(self.tree[i]);
192 }
193 }
194 }
195
196 pub fn find_prefix(&self, target: u32) -> Option<usize> {
202 if self.n == 0 {
203 return None;
204 }
205
206 let mut pos = 0usize;
207 let mut remaining = target;
208 let mut bit_mask = most_significant_bit(self.n);
209
210 while bit_mask > 0 {
211 let next = pos + bit_mask;
212 if next <= self.n && self.tree[next] <= remaining {
213 remaining -= self.tree[next];
214 pos = next;
215 }
216 bit_mask >>= 1;
217 }
218
219 if pos == 0 && self.tree.get(1).copied().unwrap_or(u32::MAX) > target {
220 None
221 } else {
222 Some(pos.saturating_sub(1)) }
224 }
225
226 pub fn resize(&mut self, new_n: usize) {
229 if new_n == self.n {
230 return;
231 }
232 let mut values: Vec<u32> = (0..self.n).map(|i| self.get(i)).collect();
234 values.resize(new_n, 0);
235 self.n = new_n;
236 self.tree = vec![0u32; new_n + 1];
237 self.rebuild(&values);
238 }
239}
240
241#[inline]
243fn lowbit(x: usize) -> usize {
244 x & x.wrapping_neg()
245}
246
247#[inline]
249fn most_significant_bit(n: usize) -> usize {
250 if n == 0 {
251 return 0;
252 }
253 1 << (usize::BITS - 1 - n.leading_zeros())
254}
255
256#[cfg(test)]
257mod tests {
258 use super::*;
259
260 #[test]
263 fn new_creates_zeroed_tree() {
264 let ft = FenwickTree::new(10);
265 assert_eq!(ft.len(), 10);
266 assert!(!ft.is_empty());
267 assert_eq!(ft.total(), 0);
268 }
269
270 #[test]
271 fn empty_tree() {
272 let ft = FenwickTree::new(0);
273 assert!(ft.is_empty());
274 assert_eq!(ft.total(), 0);
275 }
276
277 #[test]
278 fn from_values_matches_sequential() {
279 let values = vec![3, 1, 4, 1, 5, 9, 2, 6];
280 let ft = FenwickTree::from_values(&values);
281
282 assert_eq!(ft.prefix(0), 3);
284 assert_eq!(ft.prefix(1), 4);
285 assert_eq!(ft.prefix(2), 8);
286 assert_eq!(ft.prefix(7), 31);
287 assert_eq!(ft.total(), 31);
288 }
289
290 #[test]
293 fn update_and_query() {
294 let mut ft = FenwickTree::new(5);
295 ft.update(0, 10);
296 ft.update(2, 20);
297 ft.update(4, 30);
298
299 assert_eq!(ft.prefix(0), 10);
300 assert_eq!(ft.prefix(2), 30);
301 assert_eq!(ft.prefix(4), 60);
302 assert_eq!(ft.total(), 60);
303 }
304
305 #[test]
306 fn set_overwrites_value() {
307 let mut ft = FenwickTree::from_values(&[5, 10, 15]);
308 ft.set(1, 20);
309 assert_eq!(ft.get(0), 5);
310 assert_eq!(ft.get(1), 20);
311 assert_eq!(ft.get(2), 15);
312 assert_eq!(ft.total(), 40);
313 }
314
315 #[test]
316 fn get_retrieves_individual_values() {
317 let values = vec![7, 3, 8, 2, 6];
318 let ft = FenwickTree::from_values(&values);
319 for (i, &v) in values.iter().enumerate() {
320 assert_eq!(ft.get(i), v, "mismatch at index {i}");
321 }
322 }
323
324 #[test]
327 fn range_sum() {
328 let ft = FenwickTree::from_values(&[1, 2, 3, 4, 5]);
329 assert_eq!(ft.range(0, 4), 15);
330 assert_eq!(ft.range(1, 3), 9);
331 assert_eq!(ft.range(2, 2), 3);
332 assert_eq!(ft.range(0, 0), 1);
333 }
334
335 #[test]
338 fn unit_batch_update_equivalence() {
339 let values = vec![10, 20, 30, 40, 50];
340 let deltas = vec![(0, 5), (2, -3), (4, 10), (1, 7)];
341
342 let mut ft_seq = FenwickTree::from_values(&values);
344 for &(i, d) in &deltas {
345 ft_seq.update(i, d);
346 }
347
348 let mut ft_batch = FenwickTree::from_values(&values);
350 ft_batch.batch_update(&deltas);
351
352 for i in 0..5 {
354 assert_eq!(ft_seq.get(i), ft_batch.get(i), "mismatch at index {i}");
355 }
356 }
357
358 #[test]
361 fn rebuild_matches_from_values() {
362 let v1 = vec![1, 2, 3, 4, 5];
363 let v2 = vec![10, 20, 30, 40, 50];
364
365 let ft1 = FenwickTree::from_values(&v2);
366 let mut ft2 = FenwickTree::from_values(&v1);
367 ft2.rebuild(&v2);
368
369 for i in 0..5 {
370 assert_eq!(ft1.get(i), ft2.get(i));
371 }
372 }
373
374 #[test]
377 fn find_prefix_scroll_offset() {
378 let ft = FenwickTree::from_values(&[20, 30, 10, 40, 25]);
381
382 assert_eq!(ft.find_prefix(0), None);
386
387 assert_eq!(ft.find_prefix(20), Some(0));
389
390 assert_eq!(ft.find_prefix(50), Some(1));
392
393 assert_eq!(ft.find_prefix(99), Some(2));
395
396 assert_eq!(ft.find_prefix(125), Some(4));
398 }
399
400 #[test]
403 fn resize_grow_preserves() {
404 let mut ft = FenwickTree::from_values(&[1, 2, 3]);
405 ft.resize(5);
406 assert_eq!(ft.len(), 5);
407 assert_eq!(ft.get(0), 1);
408 assert_eq!(ft.get(1), 2);
409 assert_eq!(ft.get(2), 3);
410 assert_eq!(ft.get(3), 0);
411 assert_eq!(ft.get(4), 0);
412 }
413
414 #[test]
415 fn resize_shrink_drops() {
416 let mut ft = FenwickTree::from_values(&[1, 2, 3, 4, 5]);
417 ft.resize(3);
418 assert_eq!(ft.len(), 3);
419 assert_eq!(ft.total(), 6); }
421
422 #[test]
425 fn property_prefix_sum_correct() {
426 let mut seed: u64 = 0xCAFE_BABE_0000_0001;
428 let n = 100;
429 let mut naive = vec![0u32; n];
430 let mut ft = FenwickTree::new(n);
431
432 for _ in 0..500 {
433 seed = seed
434 .wrapping_mul(6364136223846793005)
435 .wrapping_add(1442695040888963407);
436 let idx = (seed >> 33) as usize % n;
437 seed = seed
438 .wrapping_mul(6364136223846793005)
439 .wrapping_add(1442695040888963407);
440 let delta = ((seed >> 33) as i32 % 100).abs();
441
442 naive[idx] = naive[idx].wrapping_add(delta as u32);
443 ft.update(idx, delta);
444 }
445
446 let mut naive_prefix = 0u32;
448 for (i, value) in naive.iter().enumerate() {
449 naive_prefix = naive_prefix.wrapping_add(*value);
450 assert_eq!(ft.prefix(i), naive_prefix, "prefix mismatch at index {i}");
451 }
452 }
453
454 #[test]
457 fn perf_fenwick_hotpath() {
458 let n = 100_000;
459 let values: Vec<u32> = (0..n).map(|i| (i % 50 + 1) as u32).collect();
460
461 let start = std::time::Instant::now();
463 let mut ft = FenwickTree::from_values(&values);
464 let build_time = start.elapsed();
465
466 let start = std::time::Instant::now();
468 for i in 0..10_000 {
469 ft.update(i * 10, 5);
470 }
471 let update_time = start.elapsed();
472
473 let start = std::time::Instant::now();
475 let mut _sink = 0u32;
476 for i in 0..10_000 {
477 _sink = _sink.wrapping_add(ft.prefix(i * 10));
478 }
479 let query_time = start.elapsed();
480
481 let deltas: Vec<(usize, i32)> = (0..10_000).map(|i| (i * 10, 3)).collect();
483 let start = std::time::Instant::now();
484 ft.batch_update(&deltas);
485 let batch_time = start.elapsed();
486
487 eprintln!("=== Fenwick Tree Performance (n={n}) ===");
489 eprintln!("Build (from_values): {:?}", build_time);
490 eprintln!("10k point updates: {:?}", update_time);
491 eprintln!("10k prefix queries: {:?}", query_time);
492 eprintln!("10k batch updates: {:?}", batch_time);
493 eprintln!("Query p50 (approx): {:?}", query_time / 10_000);
494
495 assert!(
497 query_time < std::time::Duration::from_millis(50),
498 "10k queries too slow: {query_time:?}"
499 );
500 assert!(
501 build_time < std::time::Duration::from_millis(100),
502 "build too slow: {build_time:?}"
503 );
504 }
505
506 #[test]
509 fn lowbit_correctness() {
510 assert_eq!(lowbit(1), 1);
511 assert_eq!(lowbit(2), 2);
512 assert_eq!(lowbit(3), 1);
513 assert_eq!(lowbit(4), 4);
514 assert_eq!(lowbit(6), 2);
515 assert_eq!(lowbit(8), 8);
516 assert_eq!(lowbit(12), 4);
517 }
518
519 #[test]
520 fn msb_correctness() {
521 assert_eq!(most_significant_bit(0), 0);
522 assert_eq!(most_significant_bit(1), 1);
523 assert_eq!(most_significant_bit(5), 4);
524 assert_eq!(most_significant_bit(8), 8);
525 assert_eq!(most_significant_bit(100), 64);
526 assert_eq!(most_significant_bit(1000), 512);
527 }
528}