pub struct StaticTopTree {
root: usize,
n: usize,
edge_child: Vec<usize>,
parent_edge: Vec<usize>,
compressed: Vec<InnerNode>,
raked: Vec<InnerNode>,
vertex_links: Vec<VertexLinks>,
compress_roots: Vec<Option<Slot>>,
rake_roots: Vec<Option<Slot>>,
}Fields§
§root: usize§n: usize§edge_child: Vec<usize>§parent_edge: Vec<usize>§compressed: Vec<InnerNode>§raked: Vec<InnerNode>§vertex_links: Vec<VertexLinks>§compress_roots: Vec<Option<Slot>>§rake_roots: Vec<Option<Slot>>Implementations§
Source§impl StaticTopTree
impl StaticTopTree
Sourcepub fn new(root: usize, graph: &UndirectedSparseGraph) -> Self
pub fn new(root: usize, graph: &UndirectedSparseGraph) -> Self
Sourcepub fn vertices_size(&self) -> usize
pub fn vertices_size(&self) -> usize
Examples found in repository?
crates/competitive/src/tree/static_top_tree.rs (line 287)
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 }
336
337 fn merge_compress(&mut self, left: Node, right: Node) -> Node {
338 let id = self.compressed.len();
339 self.set_parent(left.slot, id << 1);
340 self.set_parent(right.slot, id << 1 | 1);
341 self.compressed.push(InnerNode {
342 left: left.slot,
343 right: right.slot,
344 parent: usize::MAX,
345 });
346 Node {
347 depth: left.depth.max(right.depth) + 1,
348 slot: Slot::CompressInner(id),
349 }
350 }
351
352 fn merge_rake(&mut self, left: Node, right: Node) -> Node {
353 let id = self.raked.len();
354 self.set_parent(left.slot, id << 1);
355 self.set_parent(right.slot, id << 1 | 1);
356 self.raked.push(InnerNode {
357 left: left.slot,
358 right: right.slot,
359 parent: usize::MAX,
360 });
361 Node {
362 depth: left.depth.max(right.depth) + 1,
363 slot: Slot::RakeInner(id),
364 }
365 }
366
367 fn set_parent(&mut self, slot: Slot, parent: usize) {
368 match slot {
369 Slot::CompressLeaf(v) => self.vertex_links[v].compress_parent = parent,
370 Slot::CompressInner(i) => self.compressed[i].parent = parent,
371 Slot::RakeLeaf(v) => self.vertex_links[v].rake_parent = parent,
372 Slot::RakeInner(i) => self.raked[i].parent = parent,
373 }
374 }
375
376 fn init_compress<C>(
377 &self,
378 data: &mut StaticTopTreeDataBuilder<C>,
379 vertices: &[<C as Cluster>::Vertex],
380 edges: &[<C as Cluster>::Edge],
381 slot: Slot,
382 ) -> <C as Cluster>::Path
383 where
384 C: Cluster,
385 {
386 match slot {
387 Slot::CompressLeaf(vertex) => {
388 let point = self.init_point(data, vertices, edges, vertex);
389 C::add_vertex(
390 &point,
391 &vertices[vertex],
392 self.parent_edge_ref(edges, vertex),
393 )
394 }
395 Slot::CompressInner(id) => {
396 let node = &self.compressed[id];
397 let left = self.init_compress(data, vertices, edges, node.left);
398 let right = self.init_compress(data, vertices, edges, node.right);
399 data.compressed[id].write(InnerValue {
400 parent: node.parent,
401 left: left.clone(),
402 right: right.clone(),
403 });
404 C::compress(&left, &right)
405 }
406 Slot::RakeLeaf(_) | Slot::RakeInner(_) => unreachable!(),
407 }
408 }
409
410 fn fold_compress<C>(
411 &self,
412 vertices: &[<C as Cluster>::Vertex],
413 edges: &[<C as Cluster>::Edge],
414 slot: Slot,
415 ) -> <C as Cluster>::Path
416 where
417 C: Cluster,
418 {
419 match slot {
420 Slot::CompressLeaf(vertex) => {
421 let point = self.fold_point::<C>(vertices, edges, vertex);
422 C::add_vertex(
423 &point,
424 &vertices[vertex],
425 self.parent_edge_ref(edges, vertex),
426 )
427 }
428 Slot::CompressInner(id) => {
429 let node = &self.compressed[id];
430 let left = self.fold_compress::<C>(vertices, edges, node.left);
431 let right = self.fold_compress::<C>(vertices, edges, node.right);
432 C::compress(&left, &right)
433 }
434 Slot::RakeLeaf(_) | Slot::RakeInner(_) => unreachable!(),
435 }
436 }
437
438 fn init_point<C>(
439 &self,
440 data: &mut StaticTopTreeDataBuilder<C>,
441 vertices: &[<C as Cluster>::Vertex],
442 edges: &[<C as Cluster>::Edge],
443 vertex: usize,
444 ) -> <C as Cluster>::Point
445 where
446 C: Cluster,
447 {
448 let point = if let Some(slot) = self.rake_roots[vertex] {
449 self.init_rake(data, vertices, edges, slot)
450 } else {
451 C::unit_point()
452 };
453 data.light_points[vertex] = point.clone();
454 point
455 }
456
457 fn fold_point<C>(
458 &self,
459 vertices: &[<C as Cluster>::Vertex],
460 edges: &[<C as Cluster>::Edge],
461 vertex: usize,
462 ) -> <C as Cluster>::Point
463 where
464 C: Cluster,
465 {
466 if let Some(slot) = self.rake_roots[vertex] {
467 self.fold_rake::<C>(vertices, edges, slot)
468 } else {
469 C::unit_point()
470 }
471 }
472
473 fn init_rake<C>(
474 &self,
475 data: &mut StaticTopTreeDataBuilder<C>,
476 vertices: &[<C as Cluster>::Vertex],
477 edges: &[<C as Cluster>::Edge],
478 slot: Slot,
479 ) -> <C as Cluster>::Point
480 where
481 C: Cluster,
482 {
483 match slot {
484 Slot::RakeLeaf(vertex) => {
485 let path = self.init_compress(
486 data,
487 vertices,
488 edges,
489 self.compress_roots[vertex].expect("light child path must exist"),
490 );
491 C::add_edge(&path)
492 }
493 Slot::RakeInner(id) => {
494 let node = &self.raked[id];
495 let left = self.init_rake(data, vertices, edges, node.left);
496 let right = self.init_rake(data, vertices, edges, node.right);
497 data.raked[id].write(InnerValue {
498 parent: node.parent,
499 left: left.clone(),
500 right: right.clone(),
501 });
502 C::rake(&left, &right)
503 }
504 Slot::CompressLeaf(_) | Slot::CompressInner(_) => unreachable!(),
505 }
506 }
507
508 fn fold_rake<C>(
509 &self,
510 vertices: &[<C as Cluster>::Vertex],
511 edges: &[<C as Cluster>::Edge],
512 slot: Slot,
513 ) -> <C as Cluster>::Point
514 where
515 C: Cluster,
516 {
517 match slot {
518 Slot::RakeLeaf(vertex) => {
519 let path = self.fold_compress::<C>(
520 vertices,
521 edges,
522 self.compress_roots[vertex].expect("light child path must exist"),
523 );
524 C::add_edge(&path)
525 }
526 Slot::RakeInner(id) => {
527 let node = &self.raked[id];
528 let left = self.fold_rake::<C>(vertices, edges, node.left);
529 let right = self.fold_rake::<C>(vertices, edges, node.right);
530 C::rake(&left, &right)
531 }
532 Slot::CompressLeaf(_) | Slot::CompressInner(_) => unreachable!(),
533 }
534 }
535
536 fn parent_edge_ref<'a, T>(&self, edges: &'a [T], vertex: usize) -> Option<&'a T> {
537 let edge = self.parent_edge[vertex];
538 if edge == usize::MAX {
539 None
540 } else {
541 Some(&edges[edge])
542 }
543 }
544}
545
546impl<'a, C> StaticTopTreeDp<'a, C>
547where
548 C: Cluster,
549{
550 pub fn new(
551 tree: &'a StaticTopTree,
552 vertices: Vec<<C as Cluster>::Vertex>,
553 edges: Vec<<C as Cluster>::Edge>,
554 ) -> Self {
555 assert_eq!(vertices.len(), tree.vertices_size());
556 assert_eq!(edges.len(), tree.edges_size());
557
558 let mut data: StaticTopTreeDataBuilder<C> = StaticTopTreeDataBuilder::new(tree);
559 let path = tree.init_compress(
560 &mut data,
561 &vertices,
562 &edges,
563 tree.compress_roots[tree.root].expect("root compress tree must exist"),
564 );
565 let all_point = C::add_edge(&path);
566 Self {
567 tree,
568 vertices,
569 edges,
570 compressed: unsafe { assume_init_vec(data.compressed) },
571 raked: unsafe { assume_init_vec(data.raked) },
572 light_points: data.light_points,
573 all_point,
574 }
575 }Sourcepub fn edges_size(&self) -> usize
pub fn edges_size(&self) -> usize
Examples found in repository?
crates/competitive/src/tree/static_top_tree.rs (line 288)
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 }
336
337 fn merge_compress(&mut self, left: Node, right: Node) -> Node {
338 let id = self.compressed.len();
339 self.set_parent(left.slot, id << 1);
340 self.set_parent(right.slot, id << 1 | 1);
341 self.compressed.push(InnerNode {
342 left: left.slot,
343 right: right.slot,
344 parent: usize::MAX,
345 });
346 Node {
347 depth: left.depth.max(right.depth) + 1,
348 slot: Slot::CompressInner(id),
349 }
350 }
351
352 fn merge_rake(&mut self, left: Node, right: Node) -> Node {
353 let id = self.raked.len();
354 self.set_parent(left.slot, id << 1);
355 self.set_parent(right.slot, id << 1 | 1);
356 self.raked.push(InnerNode {
357 left: left.slot,
358 right: right.slot,
359 parent: usize::MAX,
360 });
361 Node {
362 depth: left.depth.max(right.depth) + 1,
363 slot: Slot::RakeInner(id),
364 }
365 }
366
367 fn set_parent(&mut self, slot: Slot, parent: usize) {
368 match slot {
369 Slot::CompressLeaf(v) => self.vertex_links[v].compress_parent = parent,
370 Slot::CompressInner(i) => self.compressed[i].parent = parent,
371 Slot::RakeLeaf(v) => self.vertex_links[v].rake_parent = parent,
372 Slot::RakeInner(i) => self.raked[i].parent = parent,
373 }
374 }
375
376 fn init_compress<C>(
377 &self,
378 data: &mut StaticTopTreeDataBuilder<C>,
379 vertices: &[<C as Cluster>::Vertex],
380 edges: &[<C as Cluster>::Edge],
381 slot: Slot,
382 ) -> <C as Cluster>::Path
383 where
384 C: Cluster,
385 {
386 match slot {
387 Slot::CompressLeaf(vertex) => {
388 let point = self.init_point(data, vertices, edges, vertex);
389 C::add_vertex(
390 &point,
391 &vertices[vertex],
392 self.parent_edge_ref(edges, vertex),
393 )
394 }
395 Slot::CompressInner(id) => {
396 let node = &self.compressed[id];
397 let left = self.init_compress(data, vertices, edges, node.left);
398 let right = self.init_compress(data, vertices, edges, node.right);
399 data.compressed[id].write(InnerValue {
400 parent: node.parent,
401 left: left.clone(),
402 right: right.clone(),
403 });
404 C::compress(&left, &right)
405 }
406 Slot::RakeLeaf(_) | Slot::RakeInner(_) => unreachable!(),
407 }
408 }
409
410 fn fold_compress<C>(
411 &self,
412 vertices: &[<C as Cluster>::Vertex],
413 edges: &[<C as Cluster>::Edge],
414 slot: Slot,
415 ) -> <C as Cluster>::Path
416 where
417 C: Cluster,
418 {
419 match slot {
420 Slot::CompressLeaf(vertex) => {
421 let point = self.fold_point::<C>(vertices, edges, vertex);
422 C::add_vertex(
423 &point,
424 &vertices[vertex],
425 self.parent_edge_ref(edges, vertex),
426 )
427 }
428 Slot::CompressInner(id) => {
429 let node = &self.compressed[id];
430 let left = self.fold_compress::<C>(vertices, edges, node.left);
431 let right = self.fold_compress::<C>(vertices, edges, node.right);
432 C::compress(&left, &right)
433 }
434 Slot::RakeLeaf(_) | Slot::RakeInner(_) => unreachable!(),
435 }
436 }
437
438 fn init_point<C>(
439 &self,
440 data: &mut StaticTopTreeDataBuilder<C>,
441 vertices: &[<C as Cluster>::Vertex],
442 edges: &[<C as Cluster>::Edge],
443 vertex: usize,
444 ) -> <C as Cluster>::Point
445 where
446 C: Cluster,
447 {
448 let point = if let Some(slot) = self.rake_roots[vertex] {
449 self.init_rake(data, vertices, edges, slot)
450 } else {
451 C::unit_point()
452 };
453 data.light_points[vertex] = point.clone();
454 point
455 }
456
457 fn fold_point<C>(
458 &self,
459 vertices: &[<C as Cluster>::Vertex],
460 edges: &[<C as Cluster>::Edge],
461 vertex: usize,
462 ) -> <C as Cluster>::Point
463 where
464 C: Cluster,
465 {
466 if let Some(slot) = self.rake_roots[vertex] {
467 self.fold_rake::<C>(vertices, edges, slot)
468 } else {
469 C::unit_point()
470 }
471 }
472
473 fn init_rake<C>(
474 &self,
475 data: &mut StaticTopTreeDataBuilder<C>,
476 vertices: &[<C as Cluster>::Vertex],
477 edges: &[<C as Cluster>::Edge],
478 slot: Slot,
479 ) -> <C as Cluster>::Point
480 where
481 C: Cluster,
482 {
483 match slot {
484 Slot::RakeLeaf(vertex) => {
485 let path = self.init_compress(
486 data,
487 vertices,
488 edges,
489 self.compress_roots[vertex].expect("light child path must exist"),
490 );
491 C::add_edge(&path)
492 }
493 Slot::RakeInner(id) => {
494 let node = &self.raked[id];
495 let left = self.init_rake(data, vertices, edges, node.left);
496 let right = self.init_rake(data, vertices, edges, node.right);
497 data.raked[id].write(InnerValue {
498 parent: node.parent,
499 left: left.clone(),
500 right: right.clone(),
501 });
502 C::rake(&left, &right)
503 }
504 Slot::CompressLeaf(_) | Slot::CompressInner(_) => unreachable!(),
505 }
506 }
507
508 fn fold_rake<C>(
509 &self,
510 vertices: &[<C as Cluster>::Vertex],
511 edges: &[<C as Cluster>::Edge],
512 slot: Slot,
513 ) -> <C as Cluster>::Point
514 where
515 C: Cluster,
516 {
517 match slot {
518 Slot::RakeLeaf(vertex) => {
519 let path = self.fold_compress::<C>(
520 vertices,
521 edges,
522 self.compress_roots[vertex].expect("light child path must exist"),
523 );
524 C::add_edge(&path)
525 }
526 Slot::RakeInner(id) => {
527 let node = &self.raked[id];
528 let left = self.fold_rake::<C>(vertices, edges, node.left);
529 let right = self.fold_rake::<C>(vertices, edges, node.right);
530 C::rake(&left, &right)
531 }
532 Slot::CompressLeaf(_) | Slot::CompressInner(_) => unreachable!(),
533 }
534 }
535
536 fn parent_edge_ref<'a, T>(&self, edges: &'a [T], vertex: usize) -> Option<&'a T> {
537 let edge = self.parent_edge[vertex];
538 if edge == usize::MAX {
539 None
540 } else {
541 Some(&edges[edge])
542 }
543 }
544}
545
546impl<'a, C> StaticTopTreeDp<'a, C>
547where
548 C: Cluster,
549{
550 pub fn new(
551 tree: &'a StaticTopTree,
552 vertices: Vec<<C as Cluster>::Vertex>,
553 edges: Vec<<C as Cluster>::Edge>,
554 ) -> Self {
555 assert_eq!(vertices.len(), tree.vertices_size());
556 assert_eq!(edges.len(), tree.edges_size());
557
558 let mut data: StaticTopTreeDataBuilder<C> = StaticTopTreeDataBuilder::new(tree);
559 let path = tree.init_compress(
560 &mut data,
561 &vertices,
562 &edges,
563 tree.compress_roots[tree.root].expect("root compress tree must exist"),
564 );
565 let all_point = C::add_edge(&path);
566 Self {
567 tree,
568 vertices,
569 edges,
570 compressed: unsafe { assume_init_vec(data.compressed) },
571 raked: unsafe { assume_init_vec(data.raked) },
572 light_points: data.light_points,
573 all_point,
574 }
575 }Sourcepub fn dp<C>(
&self,
vertices: Vec<<C as Cluster>::Vertex>,
edges: Vec<<C as Cluster>::Edge>,
) -> StaticTopTreeDp<'_, C>where
C: Cluster,
pub fn dp<C>(
&self,
vertices: Vec<<C as Cluster>::Vertex>,
edges: Vec<<C as Cluster>::Edge>,
) -> StaticTopTreeDp<'_, C>where
C: Cluster,
Examples found in repository?
crates/library_checker/src/tree/point_set_tree_path_composite_sum_fixed_root.rs (line 111)
103pub fn point_set_tree_path_composite_sum_fixed_root(reader: impl Read, writer: impl Write) {
104 prepare_io!(reader, writer);
105 sc!(n,
106 q,
107 value: [M; n],
108 (graph, edges): @TreeGraphScanner::<usize, (M, M)>::new(n));
109
110 let top_tree = graph.static_top_tree(0);
111 let mut dp = top_tree.dp::<Dp>(value, edges);
112
113 for _ in 0..q {
114 sc!(query: Query);
115 match query {
116 Query::SetVertex { v, x } => {
117 dp.set_vertex(v, x);
118 pp!(dp.fold_all().sum);
119 }
120 Query::SetEdge { e, a, b } => {
121 dp.set_edge(e, (a, b));
122 pp!(dp.fold_all().sum);
123 }
124 }
125 }
126}More examples
crates/library_checker/src/tree/point_set_tree_path_composite_sum.rs (line 145)
137pub fn point_set_tree_path_composite_sum(reader: impl Read, writer: impl Write) {
138 prepare_io!(reader, writer);
139 sc!(n,
140 q,
141 value: [M; n],
142 (graph, edges): @TreeGraphScanner::<usize, (M, M)>::new(n));
143
144 let top_tree = graph.static_top_tree(0);
145 let mut dp = top_tree.dp::<Dp>(value, edges);
146
147 for _ in 0..q {
148 sc!(query: Query);
149 match query {
150 Query::SetVertex { v, x, r } => {
151 dp.set_vertex(v, x);
152 pp!(dp.fold_path(r).reverse.sum);
153 }
154 Query::SetEdge { e, a, b, r } => {
155 dp.set_edge(e, (a, b));
156 pp!(dp.fold_path(r).reverse.sum);
157 }
158 }
159 }
160}pub fn fold_all<C>(
&self,
vertices: &[<C as Cluster>::Vertex],
edges: &[<C as Cluster>::Edge],
) -> <C as Cluster>::Pointwhere
C: Cluster,
Sourcefn build_compress(
&mut self,
vertex: usize,
heavy_child: &[usize],
mask: &[u64],
) -> Node
fn build_compress( &mut self, vertex: usize, heavy_child: &[usize], mask: &[u64], ) -> Node
Examples found in repository?
crates/competitive/src/tree/static_top_tree.rs (line 219)
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 }Sourcefn merge_compress(&mut self, left: Node, right: Node) -> Node
fn merge_compress(&mut self, left: Node, right: Node) -> Node
Examples found in repository?
crates/competitive/src/tree/static_top_tree.rs (line 314)
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 }Sourcefn merge_rake(&mut self, left: Node, right: Node) -> Node
fn merge_rake(&mut self, left: Node, right: Node) -> Node
Examples found in repository?
crates/competitive/src/tree/static_top_tree.rs (line 233)
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 }Sourcefn set_parent(&mut self, slot: Slot, parent: usize)
fn set_parent(&mut self, slot: Slot, parent: usize)
Examples found in repository?
crates/competitive/src/tree/static_top_tree.rs (line 339)
337 fn merge_compress(&mut self, left: Node, right: Node) -> Node {
338 let id = self.compressed.len();
339 self.set_parent(left.slot, id << 1);
340 self.set_parent(right.slot, id << 1 | 1);
341 self.compressed.push(InnerNode {
342 left: left.slot,
343 right: right.slot,
344 parent: usize::MAX,
345 });
346 Node {
347 depth: left.depth.max(right.depth) + 1,
348 slot: Slot::CompressInner(id),
349 }
350 }
351
352 fn merge_rake(&mut self, left: Node, right: Node) -> Node {
353 let id = self.raked.len();
354 self.set_parent(left.slot, id << 1);
355 self.set_parent(right.slot, id << 1 | 1);
356 self.raked.push(InnerNode {
357 left: left.slot,
358 right: right.slot,
359 parent: usize::MAX,
360 });
361 Node {
362 depth: left.depth.max(right.depth) + 1,
363 slot: Slot::RakeInner(id),
364 }
365 }Sourcefn init_compress<C>(
&self,
data: &mut StaticTopTreeDataBuilder<C>,
vertices: &[<C as Cluster>::Vertex],
edges: &[<C as Cluster>::Edge],
slot: Slot,
) -> <C as Cluster>::Pathwhere
C: Cluster,
fn init_compress<C>(
&self,
data: &mut StaticTopTreeDataBuilder<C>,
vertices: &[<C as Cluster>::Vertex],
edges: &[<C as Cluster>::Edge],
slot: Slot,
) -> <C as Cluster>::Pathwhere
C: Cluster,
Examples found in repository?
crates/competitive/src/tree/static_top_tree.rs (line 397)
376 fn init_compress<C>(
377 &self,
378 data: &mut StaticTopTreeDataBuilder<C>,
379 vertices: &[<C as Cluster>::Vertex],
380 edges: &[<C as Cluster>::Edge],
381 slot: Slot,
382 ) -> <C as Cluster>::Path
383 where
384 C: Cluster,
385 {
386 match slot {
387 Slot::CompressLeaf(vertex) => {
388 let point = self.init_point(data, vertices, edges, vertex);
389 C::add_vertex(
390 &point,
391 &vertices[vertex],
392 self.parent_edge_ref(edges, vertex),
393 )
394 }
395 Slot::CompressInner(id) => {
396 let node = &self.compressed[id];
397 let left = self.init_compress(data, vertices, edges, node.left);
398 let right = self.init_compress(data, vertices, edges, node.right);
399 data.compressed[id].write(InnerValue {
400 parent: node.parent,
401 left: left.clone(),
402 right: right.clone(),
403 });
404 C::compress(&left, &right)
405 }
406 Slot::RakeLeaf(_) | Slot::RakeInner(_) => unreachable!(),
407 }
408 }
409
410 fn fold_compress<C>(
411 &self,
412 vertices: &[<C as Cluster>::Vertex],
413 edges: &[<C as Cluster>::Edge],
414 slot: Slot,
415 ) -> <C as Cluster>::Path
416 where
417 C: Cluster,
418 {
419 match slot {
420 Slot::CompressLeaf(vertex) => {
421 let point = self.fold_point::<C>(vertices, edges, vertex);
422 C::add_vertex(
423 &point,
424 &vertices[vertex],
425 self.parent_edge_ref(edges, vertex),
426 )
427 }
428 Slot::CompressInner(id) => {
429 let node = &self.compressed[id];
430 let left = self.fold_compress::<C>(vertices, edges, node.left);
431 let right = self.fold_compress::<C>(vertices, edges, node.right);
432 C::compress(&left, &right)
433 }
434 Slot::RakeLeaf(_) | Slot::RakeInner(_) => unreachable!(),
435 }
436 }
437
438 fn init_point<C>(
439 &self,
440 data: &mut StaticTopTreeDataBuilder<C>,
441 vertices: &[<C as Cluster>::Vertex],
442 edges: &[<C as Cluster>::Edge],
443 vertex: usize,
444 ) -> <C as Cluster>::Point
445 where
446 C: Cluster,
447 {
448 let point = if let Some(slot) = self.rake_roots[vertex] {
449 self.init_rake(data, vertices, edges, slot)
450 } else {
451 C::unit_point()
452 };
453 data.light_points[vertex] = point.clone();
454 point
455 }
456
457 fn fold_point<C>(
458 &self,
459 vertices: &[<C as Cluster>::Vertex],
460 edges: &[<C as Cluster>::Edge],
461 vertex: usize,
462 ) -> <C as Cluster>::Point
463 where
464 C: Cluster,
465 {
466 if let Some(slot) = self.rake_roots[vertex] {
467 self.fold_rake::<C>(vertices, edges, slot)
468 } else {
469 C::unit_point()
470 }
471 }
472
473 fn init_rake<C>(
474 &self,
475 data: &mut StaticTopTreeDataBuilder<C>,
476 vertices: &[<C as Cluster>::Vertex],
477 edges: &[<C as Cluster>::Edge],
478 slot: Slot,
479 ) -> <C as Cluster>::Point
480 where
481 C: Cluster,
482 {
483 match slot {
484 Slot::RakeLeaf(vertex) => {
485 let path = self.init_compress(
486 data,
487 vertices,
488 edges,
489 self.compress_roots[vertex].expect("light child path must exist"),
490 );
491 C::add_edge(&path)
492 }
493 Slot::RakeInner(id) => {
494 let node = &self.raked[id];
495 let left = self.init_rake(data, vertices, edges, node.left);
496 let right = self.init_rake(data, vertices, edges, node.right);
497 data.raked[id].write(InnerValue {
498 parent: node.parent,
499 left: left.clone(),
500 right: right.clone(),
501 });
502 C::rake(&left, &right)
503 }
504 Slot::CompressLeaf(_) | Slot::CompressInner(_) => unreachable!(),
505 }
506 }
507
508 fn fold_rake<C>(
509 &self,
510 vertices: &[<C as Cluster>::Vertex],
511 edges: &[<C as Cluster>::Edge],
512 slot: Slot,
513 ) -> <C as Cluster>::Point
514 where
515 C: Cluster,
516 {
517 match slot {
518 Slot::RakeLeaf(vertex) => {
519 let path = self.fold_compress::<C>(
520 vertices,
521 edges,
522 self.compress_roots[vertex].expect("light child path must exist"),
523 );
524 C::add_edge(&path)
525 }
526 Slot::RakeInner(id) => {
527 let node = &self.raked[id];
528 let left = self.fold_rake::<C>(vertices, edges, node.left);
529 let right = self.fold_rake::<C>(vertices, edges, node.right);
530 C::rake(&left, &right)
531 }
532 Slot::CompressLeaf(_) | Slot::CompressInner(_) => unreachable!(),
533 }
534 }
535
536 fn parent_edge_ref<'a, T>(&self, edges: &'a [T], vertex: usize) -> Option<&'a T> {
537 let edge = self.parent_edge[vertex];
538 if edge == usize::MAX {
539 None
540 } else {
541 Some(&edges[edge])
542 }
543 }
544}
545
546impl<'a, C> StaticTopTreeDp<'a, C>
547where
548 C: Cluster,
549{
550 pub fn new(
551 tree: &'a StaticTopTree,
552 vertices: Vec<<C as Cluster>::Vertex>,
553 edges: Vec<<C as Cluster>::Edge>,
554 ) -> Self {
555 assert_eq!(vertices.len(), tree.vertices_size());
556 assert_eq!(edges.len(), tree.edges_size());
557
558 let mut data: StaticTopTreeDataBuilder<C> = StaticTopTreeDataBuilder::new(tree);
559 let path = tree.init_compress(
560 &mut data,
561 &vertices,
562 &edges,
563 tree.compress_roots[tree.root].expect("root compress tree must exist"),
564 );
565 let all_point = C::add_edge(&path);
566 Self {
567 tree,
568 vertices,
569 edges,
570 compressed: unsafe { assume_init_vec(data.compressed) },
571 raked: unsafe { assume_init_vec(data.raked) },
572 light_points: data.light_points,
573 all_point,
574 }
575 }Sourcefn fold_compress<C>(
&self,
vertices: &[<C as Cluster>::Vertex],
edges: &[<C as Cluster>::Edge],
slot: Slot,
) -> <C as Cluster>::Pathwhere
C: Cluster,
fn fold_compress<C>(
&self,
vertices: &[<C as Cluster>::Vertex],
edges: &[<C as Cluster>::Edge],
slot: Slot,
) -> <C as Cluster>::Pathwhere
C: Cluster,
Examples found in repository?
crates/competitive/src/tree/static_top_tree.rs (lines 289-293)
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 }
336
337 fn merge_compress(&mut self, left: Node, right: Node) -> Node {
338 let id = self.compressed.len();
339 self.set_parent(left.slot, id << 1);
340 self.set_parent(right.slot, id << 1 | 1);
341 self.compressed.push(InnerNode {
342 left: left.slot,
343 right: right.slot,
344 parent: usize::MAX,
345 });
346 Node {
347 depth: left.depth.max(right.depth) + 1,
348 slot: Slot::CompressInner(id),
349 }
350 }
351
352 fn merge_rake(&mut self, left: Node, right: Node) -> Node {
353 let id = self.raked.len();
354 self.set_parent(left.slot, id << 1);
355 self.set_parent(right.slot, id << 1 | 1);
356 self.raked.push(InnerNode {
357 left: left.slot,
358 right: right.slot,
359 parent: usize::MAX,
360 });
361 Node {
362 depth: left.depth.max(right.depth) + 1,
363 slot: Slot::RakeInner(id),
364 }
365 }
366
367 fn set_parent(&mut self, slot: Slot, parent: usize) {
368 match slot {
369 Slot::CompressLeaf(v) => self.vertex_links[v].compress_parent = parent,
370 Slot::CompressInner(i) => self.compressed[i].parent = parent,
371 Slot::RakeLeaf(v) => self.vertex_links[v].rake_parent = parent,
372 Slot::RakeInner(i) => self.raked[i].parent = parent,
373 }
374 }
375
376 fn init_compress<C>(
377 &self,
378 data: &mut StaticTopTreeDataBuilder<C>,
379 vertices: &[<C as Cluster>::Vertex],
380 edges: &[<C as Cluster>::Edge],
381 slot: Slot,
382 ) -> <C as Cluster>::Path
383 where
384 C: Cluster,
385 {
386 match slot {
387 Slot::CompressLeaf(vertex) => {
388 let point = self.init_point(data, vertices, edges, vertex);
389 C::add_vertex(
390 &point,
391 &vertices[vertex],
392 self.parent_edge_ref(edges, vertex),
393 )
394 }
395 Slot::CompressInner(id) => {
396 let node = &self.compressed[id];
397 let left = self.init_compress(data, vertices, edges, node.left);
398 let right = self.init_compress(data, vertices, edges, node.right);
399 data.compressed[id].write(InnerValue {
400 parent: node.parent,
401 left: left.clone(),
402 right: right.clone(),
403 });
404 C::compress(&left, &right)
405 }
406 Slot::RakeLeaf(_) | Slot::RakeInner(_) => unreachable!(),
407 }
408 }
409
410 fn fold_compress<C>(
411 &self,
412 vertices: &[<C as Cluster>::Vertex],
413 edges: &[<C as Cluster>::Edge],
414 slot: Slot,
415 ) -> <C as Cluster>::Path
416 where
417 C: Cluster,
418 {
419 match slot {
420 Slot::CompressLeaf(vertex) => {
421 let point = self.fold_point::<C>(vertices, edges, vertex);
422 C::add_vertex(
423 &point,
424 &vertices[vertex],
425 self.parent_edge_ref(edges, vertex),
426 )
427 }
428 Slot::CompressInner(id) => {
429 let node = &self.compressed[id];
430 let left = self.fold_compress::<C>(vertices, edges, node.left);
431 let right = self.fold_compress::<C>(vertices, edges, node.right);
432 C::compress(&left, &right)
433 }
434 Slot::RakeLeaf(_) | Slot::RakeInner(_) => unreachable!(),
435 }
436 }
437
438 fn init_point<C>(
439 &self,
440 data: &mut StaticTopTreeDataBuilder<C>,
441 vertices: &[<C as Cluster>::Vertex],
442 edges: &[<C as Cluster>::Edge],
443 vertex: usize,
444 ) -> <C as Cluster>::Point
445 where
446 C: Cluster,
447 {
448 let point = if let Some(slot) = self.rake_roots[vertex] {
449 self.init_rake(data, vertices, edges, slot)
450 } else {
451 C::unit_point()
452 };
453 data.light_points[vertex] = point.clone();
454 point
455 }
456
457 fn fold_point<C>(
458 &self,
459 vertices: &[<C as Cluster>::Vertex],
460 edges: &[<C as Cluster>::Edge],
461 vertex: usize,
462 ) -> <C as Cluster>::Point
463 where
464 C: Cluster,
465 {
466 if let Some(slot) = self.rake_roots[vertex] {
467 self.fold_rake::<C>(vertices, edges, slot)
468 } else {
469 C::unit_point()
470 }
471 }
472
473 fn init_rake<C>(
474 &self,
475 data: &mut StaticTopTreeDataBuilder<C>,
476 vertices: &[<C as Cluster>::Vertex],
477 edges: &[<C as Cluster>::Edge],
478 slot: Slot,
479 ) -> <C as Cluster>::Point
480 where
481 C: Cluster,
482 {
483 match slot {
484 Slot::RakeLeaf(vertex) => {
485 let path = self.init_compress(
486 data,
487 vertices,
488 edges,
489 self.compress_roots[vertex].expect("light child path must exist"),
490 );
491 C::add_edge(&path)
492 }
493 Slot::RakeInner(id) => {
494 let node = &self.raked[id];
495 let left = self.init_rake(data, vertices, edges, node.left);
496 let right = self.init_rake(data, vertices, edges, node.right);
497 data.raked[id].write(InnerValue {
498 parent: node.parent,
499 left: left.clone(),
500 right: right.clone(),
501 });
502 C::rake(&left, &right)
503 }
504 Slot::CompressLeaf(_) | Slot::CompressInner(_) => unreachable!(),
505 }
506 }
507
508 fn fold_rake<C>(
509 &self,
510 vertices: &[<C as Cluster>::Vertex],
511 edges: &[<C as Cluster>::Edge],
512 slot: Slot,
513 ) -> <C as Cluster>::Point
514 where
515 C: Cluster,
516 {
517 match slot {
518 Slot::RakeLeaf(vertex) => {
519 let path = self.fold_compress::<C>(
520 vertices,
521 edges,
522 self.compress_roots[vertex].expect("light child path must exist"),
523 );
524 C::add_edge(&path)
525 }
526 Slot::RakeInner(id) => {
527 let node = &self.raked[id];
528 let left = self.fold_rake::<C>(vertices, edges, node.left);
529 let right = self.fold_rake::<C>(vertices, edges, node.right);
530 C::rake(&left, &right)
531 }
532 Slot::CompressLeaf(_) | Slot::CompressInner(_) => unreachable!(),
533 }
534 }Sourcefn init_point<C>(
&self,
data: &mut StaticTopTreeDataBuilder<C>,
vertices: &[<C as Cluster>::Vertex],
edges: &[<C as Cluster>::Edge],
vertex: usize,
) -> <C as Cluster>::Pointwhere
C: Cluster,
fn init_point<C>(
&self,
data: &mut StaticTopTreeDataBuilder<C>,
vertices: &[<C as Cluster>::Vertex],
edges: &[<C as Cluster>::Edge],
vertex: usize,
) -> <C as Cluster>::Pointwhere
C: Cluster,
Examples found in repository?
crates/competitive/src/tree/static_top_tree.rs (line 388)
376 fn init_compress<C>(
377 &self,
378 data: &mut StaticTopTreeDataBuilder<C>,
379 vertices: &[<C as Cluster>::Vertex],
380 edges: &[<C as Cluster>::Edge],
381 slot: Slot,
382 ) -> <C as Cluster>::Path
383 where
384 C: Cluster,
385 {
386 match slot {
387 Slot::CompressLeaf(vertex) => {
388 let point = self.init_point(data, vertices, edges, vertex);
389 C::add_vertex(
390 &point,
391 &vertices[vertex],
392 self.parent_edge_ref(edges, vertex),
393 )
394 }
395 Slot::CompressInner(id) => {
396 let node = &self.compressed[id];
397 let left = self.init_compress(data, vertices, edges, node.left);
398 let right = self.init_compress(data, vertices, edges, node.right);
399 data.compressed[id].write(InnerValue {
400 parent: node.parent,
401 left: left.clone(),
402 right: right.clone(),
403 });
404 C::compress(&left, &right)
405 }
406 Slot::RakeLeaf(_) | Slot::RakeInner(_) => unreachable!(),
407 }
408 }Sourcefn fold_point<C>(
&self,
vertices: &[<C as Cluster>::Vertex],
edges: &[<C as Cluster>::Edge],
vertex: usize,
) -> <C as Cluster>::Pointwhere
C: Cluster,
fn fold_point<C>(
&self,
vertices: &[<C as Cluster>::Vertex],
edges: &[<C as Cluster>::Edge],
vertex: usize,
) -> <C as Cluster>::Pointwhere
C: Cluster,
Examples found in repository?
crates/competitive/src/tree/static_top_tree.rs (line 421)
410 fn fold_compress<C>(
411 &self,
412 vertices: &[<C as Cluster>::Vertex],
413 edges: &[<C as Cluster>::Edge],
414 slot: Slot,
415 ) -> <C as Cluster>::Path
416 where
417 C: Cluster,
418 {
419 match slot {
420 Slot::CompressLeaf(vertex) => {
421 let point = self.fold_point::<C>(vertices, edges, vertex);
422 C::add_vertex(
423 &point,
424 &vertices[vertex],
425 self.parent_edge_ref(edges, vertex),
426 )
427 }
428 Slot::CompressInner(id) => {
429 let node = &self.compressed[id];
430 let left = self.fold_compress::<C>(vertices, edges, node.left);
431 let right = self.fold_compress::<C>(vertices, edges, node.right);
432 C::compress(&left, &right)
433 }
434 Slot::RakeLeaf(_) | Slot::RakeInner(_) => unreachable!(),
435 }
436 }Sourcefn init_rake<C>(
&self,
data: &mut StaticTopTreeDataBuilder<C>,
vertices: &[<C as Cluster>::Vertex],
edges: &[<C as Cluster>::Edge],
slot: Slot,
) -> <C as Cluster>::Pointwhere
C: Cluster,
fn init_rake<C>(
&self,
data: &mut StaticTopTreeDataBuilder<C>,
vertices: &[<C as Cluster>::Vertex],
edges: &[<C as Cluster>::Edge],
slot: Slot,
) -> <C as Cluster>::Pointwhere
C: Cluster,
Examples found in repository?
crates/competitive/src/tree/static_top_tree.rs (line 449)
438 fn init_point<C>(
439 &self,
440 data: &mut StaticTopTreeDataBuilder<C>,
441 vertices: &[<C as Cluster>::Vertex],
442 edges: &[<C as Cluster>::Edge],
443 vertex: usize,
444 ) -> <C as Cluster>::Point
445 where
446 C: Cluster,
447 {
448 let point = if let Some(slot) = self.rake_roots[vertex] {
449 self.init_rake(data, vertices, edges, slot)
450 } else {
451 C::unit_point()
452 };
453 data.light_points[vertex] = point.clone();
454 point
455 }
456
457 fn fold_point<C>(
458 &self,
459 vertices: &[<C as Cluster>::Vertex],
460 edges: &[<C as Cluster>::Edge],
461 vertex: usize,
462 ) -> <C as Cluster>::Point
463 where
464 C: Cluster,
465 {
466 if let Some(slot) = self.rake_roots[vertex] {
467 self.fold_rake::<C>(vertices, edges, slot)
468 } else {
469 C::unit_point()
470 }
471 }
472
473 fn init_rake<C>(
474 &self,
475 data: &mut StaticTopTreeDataBuilder<C>,
476 vertices: &[<C as Cluster>::Vertex],
477 edges: &[<C as Cluster>::Edge],
478 slot: Slot,
479 ) -> <C as Cluster>::Point
480 where
481 C: Cluster,
482 {
483 match slot {
484 Slot::RakeLeaf(vertex) => {
485 let path = self.init_compress(
486 data,
487 vertices,
488 edges,
489 self.compress_roots[vertex].expect("light child path must exist"),
490 );
491 C::add_edge(&path)
492 }
493 Slot::RakeInner(id) => {
494 let node = &self.raked[id];
495 let left = self.init_rake(data, vertices, edges, node.left);
496 let right = self.init_rake(data, vertices, edges, node.right);
497 data.raked[id].write(InnerValue {
498 parent: node.parent,
499 left: left.clone(),
500 right: right.clone(),
501 });
502 C::rake(&left, &right)
503 }
504 Slot::CompressLeaf(_) | Slot::CompressInner(_) => unreachable!(),
505 }
506 }Sourcefn fold_rake<C>(
&self,
vertices: &[<C as Cluster>::Vertex],
edges: &[<C as Cluster>::Edge],
slot: Slot,
) -> <C as Cluster>::Pointwhere
C: Cluster,
fn fold_rake<C>(
&self,
vertices: &[<C as Cluster>::Vertex],
edges: &[<C as Cluster>::Edge],
slot: Slot,
) -> <C as Cluster>::Pointwhere
C: Cluster,
Examples found in repository?
crates/competitive/src/tree/static_top_tree.rs (line 467)
457 fn fold_point<C>(
458 &self,
459 vertices: &[<C as Cluster>::Vertex],
460 edges: &[<C as Cluster>::Edge],
461 vertex: usize,
462 ) -> <C as Cluster>::Point
463 where
464 C: Cluster,
465 {
466 if let Some(slot) = self.rake_roots[vertex] {
467 self.fold_rake::<C>(vertices, edges, slot)
468 } else {
469 C::unit_point()
470 }
471 }
472
473 fn init_rake<C>(
474 &self,
475 data: &mut StaticTopTreeDataBuilder<C>,
476 vertices: &[<C as Cluster>::Vertex],
477 edges: &[<C as Cluster>::Edge],
478 slot: Slot,
479 ) -> <C as Cluster>::Point
480 where
481 C: Cluster,
482 {
483 match slot {
484 Slot::RakeLeaf(vertex) => {
485 let path = self.init_compress(
486 data,
487 vertices,
488 edges,
489 self.compress_roots[vertex].expect("light child path must exist"),
490 );
491 C::add_edge(&path)
492 }
493 Slot::RakeInner(id) => {
494 let node = &self.raked[id];
495 let left = self.init_rake(data, vertices, edges, node.left);
496 let right = self.init_rake(data, vertices, edges, node.right);
497 data.raked[id].write(InnerValue {
498 parent: node.parent,
499 left: left.clone(),
500 right: right.clone(),
501 });
502 C::rake(&left, &right)
503 }
504 Slot::CompressLeaf(_) | Slot::CompressInner(_) => unreachable!(),
505 }
506 }
507
508 fn fold_rake<C>(
509 &self,
510 vertices: &[<C as Cluster>::Vertex],
511 edges: &[<C as Cluster>::Edge],
512 slot: Slot,
513 ) -> <C as Cluster>::Point
514 where
515 C: Cluster,
516 {
517 match slot {
518 Slot::RakeLeaf(vertex) => {
519 let path = self.fold_compress::<C>(
520 vertices,
521 edges,
522 self.compress_roots[vertex].expect("light child path must exist"),
523 );
524 C::add_edge(&path)
525 }
526 Slot::RakeInner(id) => {
527 let node = &self.raked[id];
528 let left = self.fold_rake::<C>(vertices, edges, node.left);
529 let right = self.fold_rake::<C>(vertices, edges, node.right);
530 C::rake(&left, &right)
531 }
532 Slot::CompressLeaf(_) | Slot::CompressInner(_) => unreachable!(),
533 }
534 }Sourcefn parent_edge_ref<'a, T>(&self, edges: &'a [T], vertex: usize) -> Option<&'a T>
fn parent_edge_ref<'a, T>(&self, edges: &'a [T], vertex: usize) -> Option<&'a T>
Examples found in repository?
crates/competitive/src/tree/static_top_tree.rs (line 392)
376 fn init_compress<C>(
377 &self,
378 data: &mut StaticTopTreeDataBuilder<C>,
379 vertices: &[<C as Cluster>::Vertex],
380 edges: &[<C as Cluster>::Edge],
381 slot: Slot,
382 ) -> <C as Cluster>::Path
383 where
384 C: Cluster,
385 {
386 match slot {
387 Slot::CompressLeaf(vertex) => {
388 let point = self.init_point(data, vertices, edges, vertex);
389 C::add_vertex(
390 &point,
391 &vertices[vertex],
392 self.parent_edge_ref(edges, vertex),
393 )
394 }
395 Slot::CompressInner(id) => {
396 let node = &self.compressed[id];
397 let left = self.init_compress(data, vertices, edges, node.left);
398 let right = self.init_compress(data, vertices, edges, node.right);
399 data.compressed[id].write(InnerValue {
400 parent: node.parent,
401 left: left.clone(),
402 right: right.clone(),
403 });
404 C::compress(&left, &right)
405 }
406 Slot::RakeLeaf(_) | Slot::RakeInner(_) => unreachable!(),
407 }
408 }
409
410 fn fold_compress<C>(
411 &self,
412 vertices: &[<C as Cluster>::Vertex],
413 edges: &[<C as Cluster>::Edge],
414 slot: Slot,
415 ) -> <C as Cluster>::Path
416 where
417 C: Cluster,
418 {
419 match slot {
420 Slot::CompressLeaf(vertex) => {
421 let point = self.fold_point::<C>(vertices, edges, vertex);
422 C::add_vertex(
423 &point,
424 &vertices[vertex],
425 self.parent_edge_ref(edges, vertex),
426 )
427 }
428 Slot::CompressInner(id) => {
429 let node = &self.compressed[id];
430 let left = self.fold_compress::<C>(vertices, edges, node.left);
431 let right = self.fold_compress::<C>(vertices, edges, node.right);
432 C::compress(&left, &right)
433 }
434 Slot::RakeLeaf(_) | Slot::RakeInner(_) => unreachable!(),
435 }
436 }
437
438 fn init_point<C>(
439 &self,
440 data: &mut StaticTopTreeDataBuilder<C>,
441 vertices: &[<C as Cluster>::Vertex],
442 edges: &[<C as Cluster>::Edge],
443 vertex: usize,
444 ) -> <C as Cluster>::Point
445 where
446 C: Cluster,
447 {
448 let point = if let Some(slot) = self.rake_roots[vertex] {
449 self.init_rake(data, vertices, edges, slot)
450 } else {
451 C::unit_point()
452 };
453 data.light_points[vertex] = point.clone();
454 point
455 }
456
457 fn fold_point<C>(
458 &self,
459 vertices: &[<C as Cluster>::Vertex],
460 edges: &[<C as Cluster>::Edge],
461 vertex: usize,
462 ) -> <C as Cluster>::Point
463 where
464 C: Cluster,
465 {
466 if let Some(slot) = self.rake_roots[vertex] {
467 self.fold_rake::<C>(vertices, edges, slot)
468 } else {
469 C::unit_point()
470 }
471 }
472
473 fn init_rake<C>(
474 &self,
475 data: &mut StaticTopTreeDataBuilder<C>,
476 vertices: &[<C as Cluster>::Vertex],
477 edges: &[<C as Cluster>::Edge],
478 slot: Slot,
479 ) -> <C as Cluster>::Point
480 where
481 C: Cluster,
482 {
483 match slot {
484 Slot::RakeLeaf(vertex) => {
485 let path = self.init_compress(
486 data,
487 vertices,
488 edges,
489 self.compress_roots[vertex].expect("light child path must exist"),
490 );
491 C::add_edge(&path)
492 }
493 Slot::RakeInner(id) => {
494 let node = &self.raked[id];
495 let left = self.init_rake(data, vertices, edges, node.left);
496 let right = self.init_rake(data, vertices, edges, node.right);
497 data.raked[id].write(InnerValue {
498 parent: node.parent,
499 left: left.clone(),
500 right: right.clone(),
501 });
502 C::rake(&left, &right)
503 }
504 Slot::CompressLeaf(_) | Slot::CompressInner(_) => unreachable!(),
505 }
506 }
507
508 fn fold_rake<C>(
509 &self,
510 vertices: &[<C as Cluster>::Vertex],
511 edges: &[<C as Cluster>::Edge],
512 slot: Slot,
513 ) -> <C as Cluster>::Point
514 where
515 C: Cluster,
516 {
517 match slot {
518 Slot::RakeLeaf(vertex) => {
519 let path = self.fold_compress::<C>(
520 vertices,
521 edges,
522 self.compress_roots[vertex].expect("light child path must exist"),
523 );
524 C::add_edge(&path)
525 }
526 Slot::RakeInner(id) => {
527 let node = &self.raked[id];
528 let left = self.fold_rake::<C>(vertices, edges, node.left);
529 let right = self.fold_rake::<C>(vertices, edges, node.right);
530 C::rake(&left, &right)
531 }
532 Slot::CompressLeaf(_) | Slot::CompressInner(_) => unreachable!(),
533 }
534 }
535
536 fn parent_edge_ref<'a, T>(&self, edges: &'a [T], vertex: usize) -> Option<&'a T> {
537 let edge = self.parent_edge[vertex];
538 if edge == usize::MAX {
539 None
540 } else {
541 Some(&edges[edge])
542 }
543 }
544}
545
546impl<'a, C> StaticTopTreeDp<'a, C>
547where
548 C: Cluster,
549{
550 pub fn new(
551 tree: &'a StaticTopTree,
552 vertices: Vec<<C as Cluster>::Vertex>,
553 edges: Vec<<C as Cluster>::Edge>,
554 ) -> Self {
555 assert_eq!(vertices.len(), tree.vertices_size());
556 assert_eq!(edges.len(), tree.edges_size());
557
558 let mut data: StaticTopTreeDataBuilder<C> = StaticTopTreeDataBuilder::new(tree);
559 let path = tree.init_compress(
560 &mut data,
561 &vertices,
562 &edges,
563 tree.compress_roots[tree.root].expect("root compress tree must exist"),
564 );
565 let all_point = C::add_edge(&path);
566 Self {
567 tree,
568 vertices,
569 edges,
570 compressed: unsafe { assume_init_vec(data.compressed) },
571 raked: unsafe { assume_init_vec(data.raked) },
572 light_points: data.light_points,
573 all_point,
574 }
575 }
576
577 pub fn get_vertex(&self, vertex: usize) -> &<C as Cluster>::Vertex {
578 &self.vertices[vertex]
579 }
580
581 pub fn apply_vertex<F>(&mut self, vertex: usize, f: F)
582 where
583 F: FnOnce(&mut <C as Cluster>::Vertex),
584 {
585 assert!(vertex < self.vertices.len());
586 f(&mut self.vertices[vertex]);
587 self.update_from_vertex(vertex);
588 }
589
590 pub fn set_vertex(&mut self, vertex: usize, value: <C as Cluster>::Vertex) {
591 self.apply_vertex(vertex, |x| *x = value);
592 }
593
594 pub fn get_edge(&self, edge: usize) -> &<C as Cluster>::Edge {
595 &self.edges[edge]
596 }
597
598 pub fn apply_edge<F>(&mut self, edge: usize, f: F)
599 where
600 F: FnOnce(&mut <C as Cluster>::Edge),
601 {
602 assert!(edge < self.edges.len());
603 f(&mut self.edges[edge]);
604 self.update_from_vertex(self.tree.edge_child[edge]);
605 }
606
607 pub fn set_edge(&mut self, edge: usize, value: <C as Cluster>::Edge) {
608 self.apply_edge(edge, |x| *x = value);
609 }
610
611 pub fn fold_all(&self) -> &<C as Cluster>::Point {
612 &self.all_point
613 }
614
615 #[inline(always)]
616 pub fn fold_path(&self, mut vertex: usize) -> <C as Cluster>::Path {
617 assert!(vertex < self.tree.n);
618 let mut path = C::unit_path();
619 let mut point = self.light_points[vertex].clone();
620 loop {
621 let links = self.tree.vertex_links[vertex];
622 let mut left = C::unit_path();
623 let mut right = C::unit_path();
624 let mut compress_parent = links.compress_parent;
625 while compress_parent != usize::MAX {
626 let inner = &self.compressed[compress_parent / 2];
627 if compress_parent & 1 == 0 {
628 right = C::compress(&right, &inner.right);
629 } else {
630 left = C::compress(&inner.left, &left);
631 }
632 compress_parent = inner.parent;
633 }
634 let right_point = C::add_edge(&right);
635 point = C::rake(&point, &right_point);
636 let mid = C::add_vertex(
637 &point,
638 &self.vertices[vertex],
639 self.tree.parent_edge_ref(&self.edges, vertex),
640 );
641 let mid = C::compress(&mid, &path);
642 path = C::compress(&left, &mid);
643 if links.heavy_parent == usize::MAX {
644 return path;
645 }
646
647 point = C::unit_point();
648 let mut rake_parent = links.rake_parent;
649 while rake_parent != usize::MAX {
650 let inner = &self.raked[rake_parent / 2];
651 if rake_parent & 1 == 0 {
652 point = C::rake(&point, &inner.right);
653 } else {
654 point = C::rake(&inner.left, &point);
655 }
656 rake_parent = inner.parent;
657 }
658 vertex = links.heavy_parent;
659 }
660 }
661
662 fn update_from_vertex(&mut self, mut vertex: usize) {
663 assert!(vertex < self.tree.n);
664 while vertex != usize::MAX {
665 let links = self.tree.vertex_links[vertex];
666 let base = C::add_vertex(
667 &self.light_points[vertex],
668 &self.vertices[vertex],
669 self.tree.parent_edge_ref(&self.edges, vertex),
670 );
671 let path = self.update_compress(links.compress_parent, base);
672 let point = C::add_edge(&path);
673 let point = self.update_rake(links.rake_parent, point);
674 if links.heavy_parent == usize::MAX {
675 self.all_point = point;
676 } else {
677 self.light_points[links.heavy_parent] = point;
678 }
679 vertex = links.heavy_parent;
680 }
681 }Trait Implementations§
Auto Trait Implementations§
impl Freeze for StaticTopTree
impl RefUnwindSafe for StaticTopTree
impl Send for StaticTopTree
impl Sync for StaticTopTree
impl Unpin for StaticTopTree
impl UnsafeUnpin for StaticTopTree
impl UnwindSafe for StaticTopTree
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more