Skip to main content

bit_ceil

Function bit_ceil 

Source
fn bit_ceil(x: u64) -> u64
Examples 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    }