1use crate::nodes::{Node, PersistentNode};
2
3pub struct Persistent<T: PersistentNode> {
6 nodes: Vec<T>,
7 roots: Vec<usize>,
8 n: usize,
9}
10
11impl<T> Persistent<T>
12where
13 T: PersistentNode + 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 #[allow(clippy::must_use_candidate)]
53 pub fn query(&self, version: usize, left: usize, right: usize) -> Option<T> {
54 self.query_helper(self.roots[version], left, right, 0, self.n - 1)
55 }
56
57 fn query_helper(
58 &self,
59 curr_node: usize,
60 left: usize,
61 right: usize,
62 i: usize,
63 j: usize,
64 ) -> Option<T> {
65 if j < left || right < i {
66 return None;
67 }
68 if left <= i && j <= right {
69 return Some(self.nodes[curr_node].clone());
70 }
71 let mid = (i + j) / 2;
72 let left_node = self.nodes[curr_node].left_child();
73 let right_node = self.nodes[curr_node].right_child();
74 match (
75 self.query_helper(left_node, left, right, i, mid),
76 self.query_helper(right_node, left, right, mid + 1, j),
77 ) {
78 (Some(ans_left), Some(ans_right)) => Some(Node::combine(&ans_left, &ans_right)),
79 (Some(ans_left), None) => Some(ans_left),
80 (None, Some(ans_right)) => Some(ans_right),
81 (None, None) => None,
82 }
83 }
84
85 pub fn update(&mut self, version: usize, p: usize, value: &<T as Node>::Value) {
89 let new_root = self.update_helper(self.roots[version], p, value, 0, self.n - 1);
90 self.roots.push(new_root);
91 }
92
93 fn update_helper(
94 &mut self,
95 curr_node: usize,
96 p: usize,
97 value: &<T as Node>::Value,
98 i: usize,
99 j: usize,
100 ) -> usize {
101 if j < p || p < i {
102 return curr_node;
103 }
104 let x = self.nodes.len();
105 self.nodes.push(self.nodes[curr_node].clone());
106 if i == j {
107 self.nodes[x] = Node::initialize(value);
108 return x;
109 }
110 let mid = (i + j) / 2;
111 let left_node = self.update_helper(self.nodes[x].left_child(), p, value, i, mid);
112 let right_node = self.update_helper(self.nodes[x].right_child(), p, value, mid + 1, j);
113 self.nodes[x] = Node::combine(&self.nodes[left_node], &self.nodes[right_node]);
114 self.nodes[x].set_children(left_node, right_node);
115 x
116 }
117 #[allow(clippy::must_use_candidate)]
119 pub fn versions(&self) -> usize {
120 self.roots.len()
121 }
122
123 pub fn lower_bound<F, G>(
159 &self,
160 version: usize,
161 predicate: F,
162 g: G,
163 value: <T as Node>::Value,
164 ) -> usize
165 where
166 F: Fn(&<T as Node>::Value, &<T as Node>::Value) -> bool,
167 G: Fn(&<T as Node>::Value, <T as Node>::Value) -> <T as Node>::Value,
168 {
169 self.lower_bound_helper(self.roots[version], 0, self.n - 1, predicate, g, value)
170 }
171 fn lower_bound_helper<F, G>(
172 &self,
173 curr_node: usize,
174 i: usize,
175 j: usize,
176 predicate: F,
177 g: G,
178 value: <T as Node>::Value,
179 ) -> usize
180 where
181 F: Fn(&<T as Node>::Value, &<T as Node>::Value) -> bool,
182 G: Fn(&<T as Node>::Value, <T as Node>::Value) -> <T as Node>::Value,
183 {
184 if i == j {
185 return i;
186 }
187 let mid = (i + j) / 2;
188 let left_node = self.nodes[curr_node].left_child();
189 let right_node = self.nodes[curr_node].right_child();
190 let left_value = self.nodes[left_node].value();
191 if predicate(left_value, &value) {
192 self.lower_bound_helper(left_node, i, mid, predicate, g, value)
193 } else {
194 let value = g(left_value, value);
195 self.lower_bound_helper(right_node, mid + 1, j, predicate, g, value)
196 }
197 }
198}
199#[cfg(test)]
200mod tests {
201 use crate::{
202 nodes::Node,
203 segment_tree::Persistent,
204 utils::{PersistentWrapper, Sum},
205 };
206 type PSum<T> = PersistentWrapper<Sum<T>>;
207 #[test]
208 fn non_empty_query_returns_some() {
209 let nodes: Vec<PSum<usize>> = (0..=10).map(|x| PSum::initialize(&x)).collect();
210 let segment_tree = Persistent::build(&nodes);
211 assert!(segment_tree.query(0, 0, 10).is_some());
212 }
213 #[test]
214 fn empty_query_returns_none() {
215 let nodes: Vec<PSum<usize>> = (0..=10).map(|x| PSum::initialize(&x)).collect();
216 let segment_tree = Persistent::build(&nodes);
217 assert!(segment_tree.query(0, 10, 0).is_none());
218 }
219 #[test]
220 fn normal_update_works() {
221 let nodes: Vec<PSum<usize>> = (0..=10).map(|x| PSum::initialize(&x)).collect();
222 let mut segment_tree = Persistent::build(&nodes);
223 let value = 20;
224 segment_tree.update(0, 0, &value);
225 assert_eq!(segment_tree.query(1, 0, 0).unwrap().value(), &value);
226 }
227
228 #[test]
229 fn branched_update_works() {
230 let nodes: Vec<PSum<usize>> = (0..=10).map(|x| PSum::initialize(&x)).collect();
231 let mut segment_tree = Persistent::build(&nodes);
232 let value = 20;
233 segment_tree.update(0, 0, &value);
234 segment_tree.update(0, 1, &value);
235 assert_eq!(segment_tree.query(2, 0, 0).unwrap().value(), &0);
236 assert_eq!(segment_tree.query(2, 1, 1).unwrap().value(), &value);
237 }
238
239 #[test]
240 fn query_works() {
241 let nodes: Vec<PSum<usize>> = (0..=10).map(|x| PSum::initialize(&x)).collect();
242 let segment_tree = Persistent::build(&nodes);
243 assert_eq!(segment_tree.query(0, 0, 10).unwrap().value(), &55);
244 }
245}