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 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    }