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