pub struct HeavyLightPathFold<'a, M: Monoid> {
tree: &'a HeavyLightDecomposition,
nodes: Vec<PathFoldNode<M::T>>,
}Fields§
§tree: &'a HeavyLightDecomposition§nodes: Vec<PathFoldNode<M::T>>Implementations§
Source§impl<M: Monoid> HeavyLightPathFold<'_, M>
impl<M: Monoid> HeavyLightPathFold<'_, M>
Sourcefn pull(&mut self, i: usize)
fn pull(&mut self, i: usize)
Examples found in repository?
crates/competitive/src/tree/heavy_light_decomposition.rs (line 424)
355 pub fn build_fold<M: Monoid>(&self, values: &[M::T]) -> HeavyLightPathFold<'_, M> {
356 assert_eq!(values.len(), self.len());
357 let mut fold = HeavyLightPathFold {
358 tree: self,
359 nodes: self
360 .order
361 .iter()
362 .map(|&v| PathFoldNode {
363 parent: u32::MAX,
364 children: [u32::MAX; 2],
365 priority: 0,
366 value: values[v].clone(),
367 aggregate: [values[v].clone(), values[v].clone()],
368 prefix: [values[v].clone(), values[v].clone()],
369 })
370 .collect(),
371 };
372 let mut start = 0;
373 let mut priorities = Vec::new();
374 let mut stack = Vec::new();
375 while start < self.len() {
376 let mut end = start + 1;
377 while end < self.len() && self.nodes[self.order[end]].head as usize == start {
378 end += 1;
379 }
380 priorities.clear();
381 let mut sum = 0usize;
382 for i in start..end {
383 let weight = self.subtree_size(self.order[i])
384 - if i + 1 < end {
385 self.subtree_size(self.order[i + 1])
386 } else {
387 0
388 };
389 let priority = (sum ^ (sum + weight)).ilog2();
390 sum += weight;
391 fold.nodes[i].priority = priority;
392 priorities.push(std::cmp::Reverse(priority));
393 }
394 let cartesian = CartesianTree::new(&priorities);
395 for i in start..end {
396 let parent = cartesian.parents[i - start];
397 fold.nodes[i].parent = if parent == usize::MAX {
398 u32::MAX
399 } else {
400 (parent + start) as u32
401 };
402 fold.nodes[i].children = cartesian.children[i - start].map(|v| {
403 if v == usize::MAX {
404 u32::MAX
405 } else {
406 (v + start) as u32
407 }
408 });
409 }
410 stack.clear();
411 stack.push(cartesian.root + start);
412 let mut i = 0;
413 while i < stack.len() {
414 stack.extend(
415 fold.nodes[stack[i]]
416 .children
417 .into_iter()
418 .filter(|&v| v != u32::MAX)
419 .map(|v| v as usize),
420 );
421 i += 1;
422 }
423 for &i in stack.iter().rev() {
424 fold.pull(i);
425 }
426 start = end;
427 }
428 fold
429 }
430}
431
432impl<M: Monoid> HeavyLightPathFold<'_, M> {
433 #[inline(always)]
434 fn pull(&mut self, i: usize) {
435 let [l, r] = self.nodes[i].children.map(|v| {
436 if v == u32::MAX {
437 usize::MAX
438 } else {
439 v as usize
440 }
441 });
442 self.nodes[i].prefix = if l == usize::MAX {
443 [self.nodes[i].value.clone(), self.nodes[i].value.clone()]
444 } else {
445 [
446 M::operate(&self.nodes[l].aggregate[0], &self.nodes[i].value),
447 M::operate(&self.nodes[i].value, &self.nodes[l].aggregate[1]),
448 ]
449 };
450 self.nodes[i].aggregate = if r == usize::MAX {
451 self.nodes[i].prefix.clone()
452 } else {
453 [
454 M::operate(&self.nodes[i].prefix[0], &self.nodes[r].aggregate[0]),
455 M::operate(&self.nodes[r].aggregate[1], &self.nodes[i].prefix[1]),
456 ]
457 };
458 }
459
460 pub fn set(&mut self, vertex: usize, value: M::T) {
461 let mut i = self.tree.index(vertex);
462 self.nodes[i].value = value;
463 while i != usize::MAX {
464 self.pull(i);
465 i = if self.nodes[i].parent == u32::MAX {
466 usize::MAX
467 } else {
468 self.nodes[i].parent as usize
469 };
470 }
471 }Sourcepub fn set(&mut self, vertex: usize, value: M::T)
pub fn set(&mut self, vertex: usize, value: M::T)
Examples found in repository?
crates/library_checker/src/tree/vertex_set_path_composite.rs (line 23)
14pub fn vertex_set_path_composite(reader: impl Read, writer: impl Write) {
15 prepare_io!(reader, writer);
16 sc!(n, q, ab: [(M, M); n], (graph, _): @TreeGraphScanner::<usize, ()>::new(n));
17 let hld = graph.hld(0);
18 let mut fold = hld.build_fold::<LinearOperation<_>>(&ab);
19 for _ in 0..q {
20 sc!(query: Query);
21 match query {
22 Query::Set { p, cd } => {
23 fold.set(p, cd);
24 }
25 Query::Apply { u, v, x } => {
26 let (a, b) = fold.fold_vertices(u, v);
27 pp!(a * x + b);
28 }
29 }
30 }
31}Sourcefn fold_prefix<const REVERSE: bool>(&self, k: usize) -> M::T
fn fold_prefix<const REVERSE: bool>(&self, k: usize) -> M::T
Examples found in repository?
crates/competitive/src/tree/heavy_light_decomposition.rs (line 537)
533 pub fn fold_vertices(&self, mut u: usize, mut v: usize) -> M::T {
534 let (mut left, mut right) = (M::unit(), M::unit());
535 while self.tree.nodes[u].head != self.tree.nodes[v].head {
536 if self.tree.index(u) > self.tree.index(v) {
537 left = M::operate(&left, &self.fold_prefix::<true>(self.tree.index(u)));
538 u = self.tree.nodes[u].parent as usize;
539 } else {
540 right = M::operate(&self.fold_prefix::<false>(self.tree.index(v)), &right);
541 v = self.tree.nodes[v].parent as usize;
542 }
543 }
544 let middle = if self.tree.index(u) > self.tree.index(v) {
545 self.fold_range::<true>(self.tree.index(v), self.tree.index(u))
546 } else {
547 self.fold_range::<false>(self.tree.index(u), self.tree.index(v))
548 };
549 M::operate(&M::operate(&left, &middle), &right)
550 }Sourcefn fold_range<const REVERSE: bool>(&self, l: usize, r: usize) -> M::T
fn fold_range<const REVERSE: bool>(&self, l: usize, r: usize) -> M::T
Examples found in repository?
crates/competitive/src/tree/heavy_light_decomposition.rs (line 545)
533 pub fn fold_vertices(&self, mut u: usize, mut v: usize) -> M::T {
534 let (mut left, mut right) = (M::unit(), M::unit());
535 while self.tree.nodes[u].head != self.tree.nodes[v].head {
536 if self.tree.index(u) > self.tree.index(v) {
537 left = M::operate(&left, &self.fold_prefix::<true>(self.tree.index(u)));
538 u = self.tree.nodes[u].parent as usize;
539 } else {
540 right = M::operate(&self.fold_prefix::<false>(self.tree.index(v)), &right);
541 v = self.tree.nodes[v].parent as usize;
542 }
543 }
544 let middle = if self.tree.index(u) > self.tree.index(v) {
545 self.fold_range::<true>(self.tree.index(v), self.tree.index(u))
546 } else {
547 self.fold_range::<false>(self.tree.index(u), self.tree.index(v))
548 };
549 M::operate(&M::operate(&left, &middle), &right)
550 }Sourcepub fn fold_vertices(&self, u: usize, v: usize) -> M::T
pub fn fold_vertices(&self, u: usize, v: usize) -> M::T
Folds the vertex values in u-to-v order.
Examples found in repository?
crates/library_checker/src/tree/vertex_set_path_composite.rs (line 26)
14pub fn vertex_set_path_composite(reader: impl Read, writer: impl Write) {
15 prepare_io!(reader, writer);
16 sc!(n, q, ab: [(M, M); n], (graph, _): @TreeGraphScanner::<usize, ()>::new(n));
17 let hld = graph.hld(0);
18 let mut fold = hld.build_fold::<LinearOperation<_>>(&ab);
19 for _ in 0..q {
20 sc!(query: Query);
21 match query {
22 Query::Set { p, cd } => {
23 fold.set(p, cd);
24 }
25 Query::Apply { u, v, x } => {
26 let (a, b) = fold.fold_vertices(u, v);
27 pp!(a * x + b);
28 }
29 }
30 }
31}Auto Trait Implementations§
impl<'a, M> Freeze for HeavyLightPathFold<'a, M>
impl<'a, M> RefUnwindSafe for HeavyLightPathFold<'a, M>
impl<'a, M> Send for HeavyLightPathFold<'a, M>
impl<'a, M> Sync for HeavyLightPathFold<'a, M>
impl<'a, M> Unpin for HeavyLightPathFold<'a, M>
impl<'a, M> UnsafeUnpin for HeavyLightPathFold<'a, M>
impl<'a, M> UnwindSafe for HeavyLightPathFold<'a, M>
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