fn bit_ceil(x: u64) -> u64Examples found in repository?
crates/competitive/src/tree/static_top_tree.rs (line 196)
156 pub fn new(root: usize, graph: &UndirectedSparseGraph) -> Self {
157 let n = graph.vertices_size();
158 assert!(n > 0);
159 assert!(root < n);
160 assert_eq!(graph.edges_size() + 1, n);
161
162 let RootedInfo {
163 order,
164 children_start,
165 children,
166 edge_child,
167 parent_edge,
168 } = rooted_children(graph, root);
169 let mut this = Self {
170 root,
171 n,
172 edge_child,
173 parent_edge,
174 compressed: Vec::with_capacity(n.saturating_sub(1)),
175 raked: Vec::with_capacity(n.saturating_sub(1)),
176 vertex_links: vec![
177 VertexLinks {
178 heavy_parent: usize::MAX,
179 compress_parent: usize::MAX,
180 rake_parent: usize::MAX,
181 };
182 n
183 ],
184 compress_roots: vec![None; n],
185 rake_roots: vec![None; n],
186 };
187
188 let mut heavy_child = vec![usize::MAX; n];
189 let mut mask = vec![1u64; n];
190 let mut buckets: [Vec<Node>; 64] = std::array::from_fn(|_| Vec::new());
191
192 for &u in order.iter().rev() {
193 let children = &children[children_start[u]..children_start[u + 1]];
194 let mut sum_rake = 0u64;
195 for &v in children {
196 sum_rake += bit_ceil(mask[v]) << 1;
197 }
198 mask[u] = bit_ceil(sum_rake);
199 for &v in children {
200 let child = bit_ceil(mask[v]) << 1;
201 let depth = bit_ceil(sum_rake - child).trailing_zeros() as usize;
202 let step = 1u64 << depth;
203 let cand = ((mask[v] + step - 1) >> depth << depth) + step;
204 if cand <= mask[u] {
205 mask[u] = cand;
206 heavy_child[u] = v;
207 }
208 }
209
210 let mut has = 0u64;
211 let mut num_light = 0usize;
212 for &v in children {
213 if v == heavy_child[u] {
214 continue;
215 }
216 num_light += 1;
217 let child = bit_ceil(mask[v]) << 1;
218 let depth = bit_ceil(sum_rake - child).trailing_zeros() as usize;
219 this.build_compress(v, &heavy_child, &mask);
220 buckets[depth].push(Node {
221 depth,
222 slot: Slot::RakeLeaf(v),
223 });
224 has |= 1u64 << depth;
225 }
226 if num_light == 0 {
227 continue;
228 }
229
230 while num_light > 1 {
231 let left = pop_bucket(&mut buckets, &mut has);
232 let right = pop_bucket(&mut buckets, &mut has);
233 let node = this.merge_rake(left, right);
234 let depth = node.depth;
235 buckets[depth].push(node);
236 has |= 1u64 << depth;
237 num_light -= 1;
238 }
239
240 let root = pop_bucket(&mut buckets, &mut has);
241 this.rake_roots[u] = Some(root.slot);
242 for &v0 in children {
243 if v0 == heavy_child[u] {
244 continue;
245 }
246 let rake_parent = this.vertex_links[v0].rake_parent;
247 let mut v = v0;
248 while v != usize::MAX {
249 this.vertex_links[v].heavy_parent = u;
250 this.vertex_links[v].rake_parent = rake_parent;
251 v = heavy_child[v];
252 }
253 }
254 }
255
256 this.build_compress(root, &heavy_child, &mask);
257 this
258 }
259
260 pub fn vertices_size(&self) -> usize {
261 self.n
262 }
263
264 pub fn edges_size(&self) -> usize {
265 self.edge_child.len()
266 }
267
268 pub fn dp<C>(
269 &self,
270 vertices: Vec<<C as Cluster>::Vertex>,
271 edges: Vec<<C as Cluster>::Edge>,
272 ) -> StaticTopTreeDp<'_, C>
273 where
274 C: Cluster,
275 {
276 StaticTopTreeDp::new(self, vertices, edges)
277 }
278
279 pub fn fold_all<C>(
280 &self,
281 vertices: &[<C as Cluster>::Vertex],
282 edges: &[<C as Cluster>::Edge],
283 ) -> <C as Cluster>::Point
284 where
285 C: Cluster,
286 {
287 assert_eq!(vertices.len(), self.vertices_size());
288 assert_eq!(edges.len(), self.edges_size());
289 let path = self.fold_compress::<C>(
290 vertices,
291 edges,
292 self.compress_roots[self.root].expect("root compress tree must exist"),
293 );
294 C::add_edge(&path)
295 }
296
297 fn build_compress(&mut self, mut vertex: usize, heavy_child: &[usize], mask: &[u64]) -> Node {
298 let start = vertex;
299 let mut stack = Vec::new();
300 while vertex != usize::MAX {
301 stack.push(Node {
302 depth: bit_ceil(mask[vertex]).trailing_zeros() as usize,
303 slot: Slot::CompressLeaf(vertex),
304 });
305 loop {
306 let len = stack.len();
307 if len >= 3
308 && (stack[len - 3].depth == stack[len - 2].depth
309 || stack[len - 3].depth <= stack[len - 1].depth)
310 {
311 let tail = stack.pop().unwrap();
312 let right = stack.pop().unwrap();
313 let left = stack.pop().unwrap();
314 let node = self.merge_compress(left, right);
315 stack.push(node);
316 stack.push(tail);
317 } else if len >= 2 && stack[len - 2].depth <= stack[len - 1].depth {
318 let right = stack.pop().unwrap();
319 let left = stack.pop().unwrap();
320 stack.push(self.merge_compress(left, right));
321 } else {
322 break;
323 }
324 }
325 vertex = heavy_child[vertex];
326 }
327 while stack.len() > 1 {
328 let right = stack.pop().unwrap();
329 let left = stack.pop().unwrap();
330 stack.push(self.merge_compress(left, right));
331 }
332 let root = stack.pop().unwrap();
333 self.compress_roots[start] = Some(root.slot);
334 root
335 }