1use crate::nodes::{LazyNode, Node, PersistentNode};
2
3pub struct LazyPersistent<T: PersistentNode + LazyNode> {
6 nodes: Vec<T>,
7 roots: Vec<usize>,
8 n: usize,
9}
10
11impl<T> LazyPersistent<T>
12where
13 T: PersistentNode + LazyNode + Clone,
14{
15 pub fn build(values: &[T]) -> Self {
18 let n = values.len();
19 let mut temp = Self {
20 nodes: Vec::with_capacity(4 * n),
21 roots: Vec::with_capacity(1),
22 n,
23 };
24 if n == 0 {
25 return temp;
26 }
27 let root = temp.build_helper(values, 0, n - 1);
28 temp.roots.push(root);
29 temp
30 }
31
32 fn build_helper(&mut self, values: &[T], i: usize, j: usize) -> usize {
33 let mid = (i + j) / 2;
34 if i == j {
35 let curr_node = self.nodes.len();
36 self.nodes.push(values[i].clone());
37 return curr_node;
38 }
39 let left_node = self.build_helper(values, i, mid);
40 let right_node = self.build_helper(values, mid + 1, j);
41 let curr_node = self.nodes.len();
42 self.nodes
43 .push(Node::combine(&self.nodes[left_node], &self.nodes[right_node]));
44 self.nodes[curr_node].set_children(left_node, right_node);
45 curr_node
46 }
47
48 pub fn query(&mut self, version: usize, left: usize, right: usize) -> Option<T> {
53 self.query_helper(self.roots[version], left, right, 0, self.n - 1)
54 }
55
56 fn push(&mut self, curr_node: usize, i: usize, j: usize) {
57 if self.nodes[curr_node].lazy_value().is_some() && i != j {
58 let left_node = self.nodes.len();
59 let right_node = self.nodes.len() + 1;
60 self.nodes
61 .push(self.nodes[self.nodes[curr_node].left_child()].clone());
62 self.nodes
63 .push(self.nodes[self.nodes[curr_node].right_child()].clone());
64 let (parent_slice, sons_slice) = self.nodes.split_at_mut(curr_node + 1);
65 let value = parent_slice[curr_node].lazy_value().unwrap();
66 sons_slice[left_node - curr_node - 1].update_lazy_value(value);
67 sons_slice[right_node - curr_node - 1].update_lazy_value(value);
68 }
69 self.nodes[curr_node].lazy_update(i, j);
70 }
71
72 fn query_helper(
73 &mut self,
74 curr_node: usize,
75 left: usize,
76 right: usize,
77 i: usize,
78 j: usize,
79 ) -> Option<T> {
80 if j < left || right < i {
81 return None;
82 }
83 if self.nodes[curr_node].lazy_value().is_some() {
84 self.push(curr_node, i, j);
85 }
86 if left <= i && j <= right {
87 return Some(self.nodes[curr_node].clone());
88 }
89 let mid = (i + j) / 2;
90 let left_node = self.nodes[curr_node].left_child();
91 let right_node = self.nodes[curr_node].right_child();
92 match (
93 self.query_helper(left_node, left, right, i, mid),
94 self.query_helper(right_node, left, right, mid + 1, j),
95 ) {
96 (Some(ans_left), Some(ans_right)) => Some(Node::combine(&ans_left, &ans_right)),
97 (Some(ans_left), None) => Some(ans_left),
98 (None, Some(ans_right)) => Some(ans_right),
99 (None, None) => None,
100 }
101 }
102
103 pub fn update(&mut self, version: usize, left: usize, right: usize, value: &<T as Node>::Value) {
107 let new_root = self.update_helper(self.roots[version], left, right, value, 0, self.n - 1);
108 self.roots.push(new_root);
109 }
110
111 fn update_helper(
112 &mut self,
113 curr_node: usize,
114 left: usize,
115 right: usize,
116 value: &<T as Node>::Value,
117 i: usize,
118 j: usize,
119 ) -> usize {
120 if j < left || right < i {
121 return curr_node;
122 }
123 let x = self.nodes.len();
124 self.nodes.push(self.nodes[curr_node].clone());
125 if left <= i && j <= right {
126 self.nodes[x].update_lazy_value(value);
127 self.push(x, i, j);
128 return x;
129 }
130 let mid = (i + j) / 2;
131 let left_node = self.update_helper(self.nodes[x].left_child(), left, right, value, i, mid);
132 let right_node =
133 self.update_helper(self.nodes[x].right_child(), left, right, value, mid + 1, j);
134 self.nodes[x] = Node::combine(&self.nodes[left_node], &self.nodes[right_node]);
135 self.nodes[x].set_children(left_node, right_node);
136 x
137 }
138
139 #[allow(clippy::must_use_candidate)]
141 pub fn versions(&self) -> usize {
142 self.roots.len()
143 }
144
145 pub fn lower_bound<F, G>(
181 &self,
182 version: usize,
183 predicate: F,
184 g: G,
185 value: <T as Node>::Value,
186 ) -> usize
187 where
188 F: Fn(&<T as Node>::Value, &<T as Node>::Value) -> bool,
189 G: Fn(&<T as Node>::Value, <T as Node>::Value) -> <T as Node>::Value,
190 {
191 self.lower_bound_helper(self.roots[version], 0, self.n - 1, predicate, g, value)
192 }
193 fn lower_bound_helper<F, G>(
194 &self,
195 curr_node: usize,
196 i: usize,
197 j: usize,
198 predicate: F,
199 g: G,
200 value: <T as Node>::Value,
201 ) -> usize
202 where
203 F: Fn(&<T as Node>::Value, &<T as Node>::Value) -> bool,
204 G: Fn(&<T as Node>::Value, <T as Node>::Value) -> <T as Node>::Value,
205 {
206 if i == j {
207 return i;
208 }
209 let mid = (i + j) / 2;
210 let left_node = self.nodes[curr_node].left_child();
211 let right_node = self.nodes[curr_node].right_child();
212 let left_value = self.nodes[left_node].value();
213 if predicate(left_value, &value) {
214 self.lower_bound_helper(left_node, i, mid, predicate, g, value)
215 } else {
216 let value = g(left_value, value);
217 self.lower_bound_helper(right_node, mid + 1, j, predicate, g, value)
218 }
219 }
220}
221#[cfg(test)]
222mod tests {
223 use crate::{
224 nodes::Node,
225 segment_tree::lazy_persistent::LazyPersistent,
226 utils::{PersistentWrapper, Sum},
227 };
228 type PSum<T> = PersistentWrapper<Sum<T>>;
229 #[test]
230 fn non_empty_query_returns_some() {
231 let nodes: Vec<PSum<usize>> = (0..=10).map(|x| PSum::initialize(&x)).collect();
232 let mut segment_tree = LazyPersistent::build(&nodes);
233 assert!(segment_tree.query(0, 0, 10).is_some());
234 }
235 #[test]
236 fn empty_query_returns_none() {
237 let nodes: Vec<PSum<usize>> = (0..=10).map(|x| PSum::initialize(&x)).collect();
238 let mut segment_tree = LazyPersistent::build(&nodes);
239 assert!(segment_tree.query(0, 10, 0).is_none());
240 }
241 #[test]
242 fn normal_update_works() {
243 let nodes: Vec<PSum<usize>> = (0..=10).map(|x| PSum::initialize(&x)).collect();
244 let mut segment_tree = LazyPersistent::build(&nodes);
245 let value = 20;
246 segment_tree.update(0, 0, 0, &value);
247 assert_eq!(segment_tree.query(1, 0, 0).unwrap().value(), &value);
248 }
249
250 #[test]
251 fn branched_update_works() {
252 let nodes: Vec<PSum<usize>> = (0..=10).map(|x| PSum::initialize(&x)).collect();
253 let mut segment_tree = LazyPersistent::build(&nodes);
254 let value = 20;
255 segment_tree.update(0, 0, 10, &value);
256 segment_tree.update(0, 1, 1, &value);
257 assert_eq!(segment_tree.query(2, 0, 0).unwrap().value(), &0);
258 assert_eq!(segment_tree.query(2, 1, 1).unwrap().value(), &(value + 1));
259 }
260
261 #[test]
262 fn query_works() {
263 let nodes: Vec<PSum<usize>> = (0..=10).map(|x| PSum::initialize(&x)).collect();
264 let mut segment_tree = LazyPersistent::build(&nodes);
265 assert_eq!(segment_tree.query(0, 0, 10).unwrap().value(), &55);
266 }
267}