Skip to main content

pop_bucket

Function pop_bucket 

Source
fn pop_bucket(buckets: &mut [Vec<Node>; 64], has: &mut u64) -> Node
Examples found in repository?
crates/competitive/src/tree/static_top_tree.rs (line 231)
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    }