contest_algorithms/range_query/
dynamic_arq.rs1use super::ArqSpec;
4
5pub struct DynamicArqNode<T: ArqSpec> {
6 val: T::S,
7 app: Option<T::F>,
8 down: (usize, usize),
9}
10
11impl<T: ArqSpec> Clone for DynamicArqNode<T> {
13 fn clone(&self) -> Self {
14 Self {
15 val: self.val.clone(),
16 app: self.app.clone(),
17 down: self.down,
18 }
19 }
20}
21
22impl<T: ArqSpec> Default for DynamicArqNode<T> {
23 fn default() -> Self {
24 Self {
25 val: T::identity(),
26 app: None,
27 down: (usize::max_value(), usize::max_value()),
28 }
29 }
30}
31
32impl<T: ArqSpec> DynamicArqNode<T> {
33 fn apply(&mut self, f: &T::F, size: i64) {
34 self.val = T::apply(f, &self.val, size);
35 if size > 1 {
36 let h = match self.app {
37 Some(ref g) => T::compose(f, g),
38 None => f.clone(),
39 };
40 self.app = Some(h);
41 }
42 }
43}
44
45pub type ArqView = (usize, i64);
46
47pub struct DynamicArq<T: ArqSpec> {
49 nodes: Vec<DynamicArqNode<T>>,
50 is_persistent: bool,
51}
52
53impl<T: ArqSpec> DynamicArq<T> {
54 pub fn new(is_persistent: bool) -> Self {
56 Self {
57 nodes: vec![],
58 is_persistent,
59 }
60 }
61
62 pub fn build_from_identity(&mut self, size: i64) -> ArqView {
64 self.nodes.push(DynamicArqNode::default());
65 (self.nodes.len() - 1, size)
66 }
67
68 pub fn build_from_slice(&mut self, init_val: &[T::S]) -> ArqView {
70 if init_val.len() == 1 {
71 let root = DynamicArqNode {
72 val: init_val[0].clone(),
73 ..Default::default()
74 };
75 self.nodes.push(root);
76 (self.nodes.len() - 1, 1)
77 } else {
78 let ls = init_val.len() / 2;
79 let (l_init, r_init) = init_val.split_at(ls);
80 let l_view = self.build_from_slice(l_init);
81 let r_view = self.build_from_slice(r_init);
82 self.merge_equal_sized(l_view, r_view)
83 }
84 }
85
86 pub fn merge_equal_sized(&mut self, (lp, ls): ArqView, (rp, rs): ArqView) -> ArqView {
88 assert!(ls == rs || ls + 1 == rs);
89 let p = self.nodes.len();
90 let root = DynamicArqNode {
91 down: (lp, rp),
92 ..Default::default()
93 };
94 self.nodes.push(root);
95 self.pull(p);
96 (p, ls + rs)
97 }
98
99 pub fn push(&mut self, (p, s): ArqView) -> (ArqView, ArqView) {
100 if self.nodes[p].down.0 == usize::max_value() {
101 self.nodes.push(DynamicArqNode::default());
102 self.nodes.push(DynamicArqNode::default());
103 self.nodes[p].down = (self.nodes.len() - 2, self.nodes.len() - 1)
104 };
105 let (lp, rp) = self.nodes[p].down;
106 let ls = s / 2;
107 if let Some(ref f) = self.nodes[p].app.take() {
108 self.nodes[lp].apply(f, ls);
109 self.nodes[rp].apply(f, s - ls);
110 }
111 ((lp, ls), (rp, s - ls))
112 }
113
114 pub fn pull(&mut self, p: usize) {
115 let (lp, rp) = self.nodes[p].down;
116 let left_val = &self.nodes[lp].val;
117 let right_val = &self.nodes[rp].val;
118 self.nodes[p].val = T::op(left_val, right_val);
119 }
120
121 fn clone_node(&mut self, p_orig: usize) -> usize {
122 if self.is_persistent {
123 let node = self.nodes[p_orig].clone();
124 self.nodes.push(node);
125 self.nodes.len() - 1
126 } else {
127 p_orig
128 }
129 }
130
131 pub fn update(&mut self, view: ArqView, l: i64, r: i64, f: &T::F) -> ArqView {
134 let (p_orig, s) = view;
135 if r < 0 || s - 1 < l {
136 view
137 } else if l <= 0 && s - 1 <= r {
138 let p_clone = self.clone_node(p_orig);
139 self.nodes[p_clone].apply(f, s);
140 (p_clone, s)
141 } else {
142 let (l_view, r_view) = self.push(view);
143 let ls = l_view.1;
144 let p_clone = self.clone_node(p_orig);
145 let lp_clone = self.update(l_view, l, r, f).0;
146 let rp_clone = self.update(r_view, l - ls, r - ls, f).0;
147 self.nodes[p_clone].down = (lp_clone, rp_clone);
148 self.pull(p_clone);
149 (p_clone, s)
150 }
151 }
152
153 pub fn query(&mut self, view: ArqView, l: i64, r: i64) -> T::S {
155 let (p, s) = view;
156 if r < 0 || s - 1 < l {
157 T::identity()
158 } else if l <= 0 && s - 1 <= r {
159 self.nodes[p].val.clone()
160 } else {
161 let (l_view, r_view) = self.push(view);
162 let ls = l_view.1;
163 let l_agg = self.query(l_view, l, r);
164 let r_agg = self.query(r_view, l - ls, r - ls);
165 T::op(&l_agg, &r_agg)
166 }
167 }
168}
169
170pub fn first_negative(arq: &mut DynamicArq<super::specs::AssignMin>, view: ArqView) -> Option<i64> {
173 let (p, s) = view;
174 if s == 1 {
175 Some(0).filter(|_| arq.nodes[p].val < 0)
176 } else {
177 let (l_view, r_view) = arq.push(view);
178 let (lp, ls) = l_view;
179 if arq.nodes[lp].val < 0 {
180 first_negative(arq, l_view)
181 } else {
182 first_negative(arq, r_view).map(|x| ls + x)
183 }
184 }
185}