pub struct ReRooting<'a, M: Monoid, F: Fn(&M::T, usize, Option<usize>) -> M::T> {
graph: &'a UndirectedSparseGraph,
pub dp: Vec<M::T>,
pub ep: Vec<M::T>,
rooting: F,
}Expand description
dynamic programming on all-rooted trees
Neighbors are merged in adjacency order before applying rooting.
Fields§
§graph: &'a UndirectedSparseGraph§dp: Vec<M::T>dp[v]: result of v-rooted tree
ep: Vec<M::T>ep[e]: result of e-subtree; e >= m denotes the reverse direction.
rooting: Frooting(data, vid, (Optional)eid): add root node(vid), result subtree is edge(eid)
Implementations§
Source§impl<'a, M, F> ReRooting<'a, M, F>
impl<'a, M, F> ReRooting<'a, M, F>
Sourcepub fn new(graph: &'a UndirectedSparseGraph, rooting: F) -> Self
pub fn new(graph: &'a UndirectedSparseGraph, rooting: F) -> Self
Sourcepub fn new_with_inverse(graph: &'a UndirectedSparseGraph, rooting: F) -> Selfwhere
M: AbelianGroup,
pub fn new_with_inverse(graph: &'a UndirectedSparseGraph, rooting: F) -> Selfwhere
M: AbelianGroup,
Examples found in repository?
crates/library_checker/src/tree/tree_path_composite_sum.rs (lines 11-23)
8pub fn tree_path_composite_sum(reader: impl Read, writer: impl Write) {
9 prepare_io!(reader, writer);
10 sc!(n, values: [M; n], (graph, edges): @TreeGraphScanner::<usize, (M, M)>::new(n));
11 let dp = ReRooting::<(AdditiveOperation<M>, AdditiveOperation<i32>), _>::new_with_inverse(
12 &graph,
13 |&(sum, count), v, edge| {
14 let sum = sum + values[v];
15 let count = count + 1;
16 if let Some(edge) = edge {
17 let (a, b) = edges[edge];
18 (a * sum + b * M::new_unchecked(count as u32), count)
19 } else {
20 (sum, count)
21 }
22 },
23 );
24 pp!(@it dp.dp.iter().map(|value| value.0));
25}Sourcefn build<I>(
graph: &'a UndirectedSparseGraph,
rooting: F,
inverse: Option<I>,
) -> Self
fn build<I>( graph: &'a UndirectedSparseGraph, rooting: F, inverse: Option<I>, ) -> Self
Sourcefn eidx(&self, u: usize, a: Neighbor<usize, usize>) -> usize
fn eidx(&self, u: usize, a: Neighbor<usize, usize>) -> usize
Examples found in repository?
crates/competitive/src/tree/rerooting.rs (line 81)
72 fn rerooting<I: Fn(&M::T, &M::T) -> M::T>(&mut self, inverse: Option<I>) {
73 let (order, parents) = self.graph.tree_order(0);
74 for &u in order.iter().skip(1).rev() {
75 let mut sum = M::unit();
76 let mut parent = None;
77 for a in self.graph.neighbors(u) {
78 if a.to == parents[u] {
79 parent = Some(a);
80 } else {
81 sum = self.merge(&sum, &self.ep[self.eidx(u, a)]);
82 }
83 }
84 let a = parent.unwrap();
85 let i = self.reidx(u, a);
86 self.ep[i] = self.add_subroot(&sum, u, a.label);
87 if inverse.is_some() {
88 self.dp[u] = sum;
89 }
90 }
91 if let Some(inverse) = inverse {
92 for u in order {
93 let sum = if u == 0 {
94 self.graph.neighbors(u).fold(M::unit(), |sum, a| {
95 self.merge(&sum, &self.ep[self.eidx(u, a)])
96 })
97 } else {
98 let a = self
99 .graph
100 .neighbors(u)
101 .find(|a| a.to == parents[u])
102 .unwrap();
103 self.merge(&self.dp[u], &self.ep[self.eidx(u, a)])
104 };
105 self.dp[u] = self.add_root(&sum, u);
106 for a in self.graph.neighbors(u) {
107 if a.to != parents[u] {
108 let value = inverse(&sum, &self.ep[self.eidx(u, a)]);
109 let i = self.reidx(u, a);
110 self.ep[i] = self.add_subroot(&value, u, a.label);
111 }
112 }
113 }
114 return;
115 }
116 let mut prefix = Vec::new();
117 for u in order {
118 prefix.clear();
119 prefix.push(M::unit());
120 for a in self.graph.neighbors(u) {
121 prefix.push(self.merge(prefix.last().unwrap(), &self.ep[self.eidx(u, a)]));
122 }
123 self.dp[u] = self.add_root(prefix.last().unwrap(), u);
124 let mut suffix = M::unit();
125 for (k, a) in self.graph.neighbors(u).enumerate().rev() {
126 if a.to != parents[u] {
127 let i = self.reidx(u, a);
128 self.ep[i] = self.add_subroot(&self.merge(&prefix[k], &suffix), u, a.label);
129 }
130 suffix = self.merge(&self.ep[self.eidx(u, a)], &suffix);
131 }
132 }
133 }Sourcefn reidx(&self, u: usize, a: Neighbor<usize, usize>) -> usize
fn reidx(&self, u: usize, a: Neighbor<usize, usize>) -> usize
Examples found in repository?
crates/competitive/src/tree/rerooting.rs (line 85)
72 fn rerooting<I: Fn(&M::T, &M::T) -> M::T>(&mut self, inverse: Option<I>) {
73 let (order, parents) = self.graph.tree_order(0);
74 for &u in order.iter().skip(1).rev() {
75 let mut sum = M::unit();
76 let mut parent = None;
77 for a in self.graph.neighbors(u) {
78 if a.to == parents[u] {
79 parent = Some(a);
80 } else {
81 sum = self.merge(&sum, &self.ep[self.eidx(u, a)]);
82 }
83 }
84 let a = parent.unwrap();
85 let i = self.reidx(u, a);
86 self.ep[i] = self.add_subroot(&sum, u, a.label);
87 if inverse.is_some() {
88 self.dp[u] = sum;
89 }
90 }
91 if let Some(inverse) = inverse {
92 for u in order {
93 let sum = if u == 0 {
94 self.graph.neighbors(u).fold(M::unit(), |sum, a| {
95 self.merge(&sum, &self.ep[self.eidx(u, a)])
96 })
97 } else {
98 let a = self
99 .graph
100 .neighbors(u)
101 .find(|a| a.to == parents[u])
102 .unwrap();
103 self.merge(&self.dp[u], &self.ep[self.eidx(u, a)])
104 };
105 self.dp[u] = self.add_root(&sum, u);
106 for a in self.graph.neighbors(u) {
107 if a.to != parents[u] {
108 let value = inverse(&sum, &self.ep[self.eidx(u, a)]);
109 let i = self.reidx(u, a);
110 self.ep[i] = self.add_subroot(&value, u, a.label);
111 }
112 }
113 }
114 return;
115 }
116 let mut prefix = Vec::new();
117 for u in order {
118 prefix.clear();
119 prefix.push(M::unit());
120 for a in self.graph.neighbors(u) {
121 prefix.push(self.merge(prefix.last().unwrap(), &self.ep[self.eidx(u, a)]));
122 }
123 self.dp[u] = self.add_root(prefix.last().unwrap(), u);
124 let mut suffix = M::unit();
125 for (k, a) in self.graph.neighbors(u).enumerate().rev() {
126 if a.to != parents[u] {
127 let i = self.reidx(u, a);
128 self.ep[i] = self.add_subroot(&self.merge(&prefix[k], &suffix), u, a.label);
129 }
130 suffix = self.merge(&self.ep[self.eidx(u, a)], &suffix);
131 }
132 }
133 }Sourcefn merge(&self, x: &M::T, y: &M::T) -> M::T
fn merge(&self, x: &M::T, y: &M::T) -> M::T
Examples found in repository?
crates/competitive/src/tree/rerooting.rs (line 81)
72 fn rerooting<I: Fn(&M::T, &M::T) -> M::T>(&mut self, inverse: Option<I>) {
73 let (order, parents) = self.graph.tree_order(0);
74 for &u in order.iter().skip(1).rev() {
75 let mut sum = M::unit();
76 let mut parent = None;
77 for a in self.graph.neighbors(u) {
78 if a.to == parents[u] {
79 parent = Some(a);
80 } else {
81 sum = self.merge(&sum, &self.ep[self.eidx(u, a)]);
82 }
83 }
84 let a = parent.unwrap();
85 let i = self.reidx(u, a);
86 self.ep[i] = self.add_subroot(&sum, u, a.label);
87 if inverse.is_some() {
88 self.dp[u] = sum;
89 }
90 }
91 if let Some(inverse) = inverse {
92 for u in order {
93 let sum = if u == 0 {
94 self.graph.neighbors(u).fold(M::unit(), |sum, a| {
95 self.merge(&sum, &self.ep[self.eidx(u, a)])
96 })
97 } else {
98 let a = self
99 .graph
100 .neighbors(u)
101 .find(|a| a.to == parents[u])
102 .unwrap();
103 self.merge(&self.dp[u], &self.ep[self.eidx(u, a)])
104 };
105 self.dp[u] = self.add_root(&sum, u);
106 for a in self.graph.neighbors(u) {
107 if a.to != parents[u] {
108 let value = inverse(&sum, &self.ep[self.eidx(u, a)]);
109 let i = self.reidx(u, a);
110 self.ep[i] = self.add_subroot(&value, u, a.label);
111 }
112 }
113 }
114 return;
115 }
116 let mut prefix = Vec::new();
117 for u in order {
118 prefix.clear();
119 prefix.push(M::unit());
120 for a in self.graph.neighbors(u) {
121 prefix.push(self.merge(prefix.last().unwrap(), &self.ep[self.eidx(u, a)]));
122 }
123 self.dp[u] = self.add_root(prefix.last().unwrap(), u);
124 let mut suffix = M::unit();
125 for (k, a) in self.graph.neighbors(u).enumerate().rev() {
126 if a.to != parents[u] {
127 let i = self.reidx(u, a);
128 self.ep[i] = self.add_subroot(&self.merge(&prefix[k], &suffix), u, a.label);
129 }
130 suffix = self.merge(&self.ep[self.eidx(u, a)], &suffix);
131 }
132 }
133 }Sourcefn add_subroot(&self, x: &M::T, vid: usize, eid: usize) -> M::T
fn add_subroot(&self, x: &M::T, vid: usize, eid: usize) -> M::T
Examples found in repository?
crates/competitive/src/tree/rerooting.rs (line 86)
72 fn rerooting<I: Fn(&M::T, &M::T) -> M::T>(&mut self, inverse: Option<I>) {
73 let (order, parents) = self.graph.tree_order(0);
74 for &u in order.iter().skip(1).rev() {
75 let mut sum = M::unit();
76 let mut parent = None;
77 for a in self.graph.neighbors(u) {
78 if a.to == parents[u] {
79 parent = Some(a);
80 } else {
81 sum = self.merge(&sum, &self.ep[self.eidx(u, a)]);
82 }
83 }
84 let a = parent.unwrap();
85 let i = self.reidx(u, a);
86 self.ep[i] = self.add_subroot(&sum, u, a.label);
87 if inverse.is_some() {
88 self.dp[u] = sum;
89 }
90 }
91 if let Some(inverse) = inverse {
92 for u in order {
93 let sum = if u == 0 {
94 self.graph.neighbors(u).fold(M::unit(), |sum, a| {
95 self.merge(&sum, &self.ep[self.eidx(u, a)])
96 })
97 } else {
98 let a = self
99 .graph
100 .neighbors(u)
101 .find(|a| a.to == parents[u])
102 .unwrap();
103 self.merge(&self.dp[u], &self.ep[self.eidx(u, a)])
104 };
105 self.dp[u] = self.add_root(&sum, u);
106 for a in self.graph.neighbors(u) {
107 if a.to != parents[u] {
108 let value = inverse(&sum, &self.ep[self.eidx(u, a)]);
109 let i = self.reidx(u, a);
110 self.ep[i] = self.add_subroot(&value, u, a.label);
111 }
112 }
113 }
114 return;
115 }
116 let mut prefix = Vec::new();
117 for u in order {
118 prefix.clear();
119 prefix.push(M::unit());
120 for a in self.graph.neighbors(u) {
121 prefix.push(self.merge(prefix.last().unwrap(), &self.ep[self.eidx(u, a)]));
122 }
123 self.dp[u] = self.add_root(prefix.last().unwrap(), u);
124 let mut suffix = M::unit();
125 for (k, a) in self.graph.neighbors(u).enumerate().rev() {
126 if a.to != parents[u] {
127 let i = self.reidx(u, a);
128 self.ep[i] = self.add_subroot(&self.merge(&prefix[k], &suffix), u, a.label);
129 }
130 suffix = self.merge(&self.ep[self.eidx(u, a)], &suffix);
131 }
132 }
133 }Sourcefn add_root(&self, x: &M::T, vid: usize) -> M::T
fn add_root(&self, x: &M::T, vid: usize) -> M::T
Examples found in repository?
crates/competitive/src/tree/rerooting.rs (line 105)
72 fn rerooting<I: Fn(&M::T, &M::T) -> M::T>(&mut self, inverse: Option<I>) {
73 let (order, parents) = self.graph.tree_order(0);
74 for &u in order.iter().skip(1).rev() {
75 let mut sum = M::unit();
76 let mut parent = None;
77 for a in self.graph.neighbors(u) {
78 if a.to == parents[u] {
79 parent = Some(a);
80 } else {
81 sum = self.merge(&sum, &self.ep[self.eidx(u, a)]);
82 }
83 }
84 let a = parent.unwrap();
85 let i = self.reidx(u, a);
86 self.ep[i] = self.add_subroot(&sum, u, a.label);
87 if inverse.is_some() {
88 self.dp[u] = sum;
89 }
90 }
91 if let Some(inverse) = inverse {
92 for u in order {
93 let sum = if u == 0 {
94 self.graph.neighbors(u).fold(M::unit(), |sum, a| {
95 self.merge(&sum, &self.ep[self.eidx(u, a)])
96 })
97 } else {
98 let a = self
99 .graph
100 .neighbors(u)
101 .find(|a| a.to == parents[u])
102 .unwrap();
103 self.merge(&self.dp[u], &self.ep[self.eidx(u, a)])
104 };
105 self.dp[u] = self.add_root(&sum, u);
106 for a in self.graph.neighbors(u) {
107 if a.to != parents[u] {
108 let value = inverse(&sum, &self.ep[self.eidx(u, a)]);
109 let i = self.reidx(u, a);
110 self.ep[i] = self.add_subroot(&value, u, a.label);
111 }
112 }
113 }
114 return;
115 }
116 let mut prefix = Vec::new();
117 for u in order {
118 prefix.clear();
119 prefix.push(M::unit());
120 for a in self.graph.neighbors(u) {
121 prefix.push(self.merge(prefix.last().unwrap(), &self.ep[self.eidx(u, a)]));
122 }
123 self.dp[u] = self.add_root(prefix.last().unwrap(), u);
124 let mut suffix = M::unit();
125 for (k, a) in self.graph.neighbors(u).enumerate().rev() {
126 if a.to != parents[u] {
127 let i = self.reidx(u, a);
128 self.ep[i] = self.add_subroot(&self.merge(&prefix[k], &suffix), u, a.label);
129 }
130 suffix = self.merge(&self.ep[self.eidx(u, a)], &suffix);
131 }
132 }
133 }Sourcefn rerooting<I: Fn(&M::T, &M::T) -> M::T>(&mut self, inverse: Option<I>)
fn rerooting<I: Fn(&M::T, &M::T) -> M::T>(&mut self, inverse: Option<I>)
Examples found in repository?
crates/competitive/src/tree/rerooting.rs (line 49)
37 fn build<I>(graph: &'a UndirectedSparseGraph, rooting: F, inverse: Option<I>) -> Self
38 where
39 I: Fn(&M::T, &M::T) -> M::T,
40 {
41 let dp = vec![M::unit(); graph.vertices_size()];
42 let ep = vec![M::unit(); graph.vertices_size() * 2];
43 let mut self_ = Self {
44 graph,
45 dp,
46 ep,
47 rooting,
48 };
49 self_.rerooting(inverse);
50 self_
51 }Trait Implementations§
Auto Trait Implementations§
impl<'a, M, F> Freeze for ReRooting<'a, M, F>
impl<'a, M, F> RefUnwindSafe for ReRooting<'a, M, F>
impl<'a, M, F> Send for ReRooting<'a, M, F>
impl<'a, M, F> Sync for ReRooting<'a, M, F>
impl<'a, M, F> Unpin for ReRooting<'a, M, F>
impl<'a, M, F> UnsafeUnpin for ReRooting<'a, M, F>
impl<'a, M, F> UnwindSafe for ReRooting<'a, M, F>
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