haar_lib/ds/
dynamic_dual_segtree.rs1use crate::algebra::traits::Monoid;
3use crate::misc::nullable_usize::NullableUsize;
4use std::ops::Range;
5
6#[derive(Clone, Debug)]
7struct Node<T> {
8 value: T,
9 left: NullableUsize,
10 right: NullableUsize,
11}
12
13impl<T> Node<T> {
14 fn new(value: T) -> Self {
15 Self {
16 value,
17 left: NullableUsize::NULL,
18 right: NullableUsize::NULL,
19 }
20 }
21}
22
23#[derive(Clone, Debug)]
25pub struct DynamicDualSegtree<M: Monoid> {
26 data: Vec<Node<M>>,
27 root: NullableUsize,
28 to: usize,
29}
30
31impl<M: Monoid + Clone> Default for DynamicDualSegtree<M> {
32 fn default() -> Self {
33 Self::new()
34 }
35}
36
37impl<M: Monoid + Clone> DynamicDualSegtree<M> {
38 pub fn new() -> Self {
40 Self {
41 data: vec![Node::new(M::id())],
42 root: NullableUsize(0),
43 to: 1,
44 }
45 }
46
47 fn propagate(&mut self, cur: usize, from: usize, to: usize) {
48 if to - from > 1 {
49 let mut cur_node = self.data[cur].clone();
50 let value = cur_node.value.clone();
51
52 let left = cur_node.left;
53 if left.is_null() {
54 let t = Node::new(M::id());
55 cur_node.left = NullableUsize(self.data.len());
56 self.data.push(t);
57 }
58 let left = cur_node.left.0;
59 let lv = self.data[left].value.clone();
60 self.data[left].value = M::op(lv, value.clone());
61
62 let right = cur_node.right;
63 if right.is_null() {
64 let t = Node::new(M::id());
65 cur_node.right = NullableUsize(self.data.len());
66 self.data.push(t);
67 }
68 let right = cur_node.right.0;
69 let rv = self.data[right].value.clone();
70 self.data[right].value = M::op(rv, value);
71
72 cur_node.value = M::id();
73 self.data[cur] = cur_node;
74 }
75 }
76
77 #[allow(clippy::collapsible_else_if)]
78 fn update_(&mut self, cur: usize, from: usize, to: usize, s: usize, t: usize, value: &M) {
79 if to - from == 1 {
80 if s <= from && to <= t {
81 let cur_value = unsafe { self.data.get_unchecked(cur).value.clone() };
82 unsafe {
83 self.data.get_unchecked_mut(cur).value = M::op(cur_value, value.clone());
84 }
85 }
86 } else {
87 if to < s || t < from {
88 } else if s <= from && to <= t {
89 let cur_value = unsafe { self.data.get_unchecked(cur).value.clone() };
90 unsafe {
91 self.data.get_unchecked_mut(cur).value = M::op(cur_value, value.clone());
92 }
93 } else {
94 let mid = (from + to) / 2;
95 self.propagate(cur, from, to);
96 let cur = unsafe { self.data.get_unchecked(cur) };
97 let left = cur.left;
98 let right = cur.right;
99 self.update_(left.0, from, mid, s, t, value);
100 self.update_(right.0, mid, to, s, t, value);
101 }
102 }
103 }
104
105 pub fn update(&mut self, Range { start: s, end: t }: Range<usize>, value: M) {
107 loop {
108 let root = self.root.0;
109
110 if t <= self.to {
111 break;
112 }
113 self.to *= 2;
114
115 let mut new_root = Node::new(M::id());
116 new_root.left = NullableUsize(root);
117
118 self.root = NullableUsize(self.data.len());
119 self.data.push(new_root);
120 }
121
122 self.update_(self.root.0, 0, self.to, s, t, &value);
123 }
124
125 fn get_(&mut self, cur: usize, from: usize, to: usize, i: usize) -> M {
126 if !(from..to).contains(&i) {
127 return M::id();
128 }
129
130 if to - from == 1 {
131 unsafe { self.data.get_unchecked(cur).value.clone() }
132 } else {
133 self.propagate(cur, from, to);
134
135 let mid = (from + to) / 2;
136 let cur = unsafe { self.data.get_unchecked(cur) };
137 if i < mid {
138 self.get_(cur.left.0, from, mid, i)
139 } else {
140 self.get_(cur.right.0, mid, to, i)
141 }
142 }
143 }
144
145 pub fn get(&mut self, i: usize) -> M {
147 self.get_(self.root.0, 0, self.to, i)
148 }
149}
150
151#[cfg(test)]
152mod tests {
153 use super::*;
154 use crate::algebra::sum::*;
155 use my_testtools::*;
156 use rand::Rng;
157
158 #[test]
159 fn test() {
160 let n = 1000;
161
162 let mut a = vec![Sum::id(); n];
163 let mut seg = DynamicDualSegtree::<Sum<u32>>::new();
164
165 let mut rng = rand::thread_rng();
166
167 for _ in 0..100 {
168 let lr = rand_range(&mut rng, 0..n);
169 let x = rng.gen_range(0..10000);
170
171 seg.update(lr.clone(), Sum(x));
172 a[lr].iter_mut().for_each(|e| e.op_assign_r(Sum(x)));
173
174 assert_eq!(a, (0..n).map(|i| seg.get(i)).collect::<Vec<_>>());
175 }
176 }
177}