88// Reference:
99// - https://atcoder.jp/contests/abc222/editorial/2749
1010// - https://null-mn.hatenablog.com/entry/2020/04/14/124151
11- template <class Edge , class St , class Ch , Ch (*merge)(Ch, Ch), Ch (*f)(St, int , Edge),
12- St (*g)(Ch, int ), Ch (*e)()>
11+ template <class Edge , class Subtree , class Children , Children (*rake)(Children, Children),
12+ Children (*add_edge)(Subtree, int , Edge), Subtree (*add_vertex)(Children, int ),
13+ Children (*e)()>
1314struct rerooting {
1415 int n_;
1516 std::vector<int > par, visited;
1617 std::vector<std::vector<std::pair<int , Edge>>> to;
17- std::vector<St > dp_subtree;
18- std::vector<St > dp_par;
19- std::vector<St > dpall;
18+ std::vector<Subtree > dp_subtree;
19+ std::vector<Subtree > dp_par;
20+ std::vector<Subtree > dpall;
2021 rerooting (const std::vector<std::vector<std::pair<int , Edge>>> &to_)
2122 : n_ (to_.size ()), par (n_, -1 ), visited (n_, 0 ), to (to_) {
22- for (int i = 0 ; i < n_; ++i) dp_subtree.push_back (g (e (), i));
23+ for (int i = 0 ; i < n_; ++i) dp_subtree.push_back (add_vertex (e (), i));
2324 dp_par = dpall = dp_subtree;
2425 }
2526
@@ -41,33 +42,33 @@ struct rerooting {
4142
4243 for (int t = int (visorder.size ()) - 1 ; t >= 0 ; --t) {
4344 int now = visorder[t];
44- Ch ch = e ();
45+ Children ch = e ();
4546 for (const auto &edge : to[now]) {
4647 int nxt = edge.first ;
4748 if (nxt == par[now]) continue ;
48- ch = merge (ch, f (dp_subtree[nxt], nxt, edge.second ));
49+ ch = rake (ch, add_edge (dp_subtree[nxt], nxt, edge.second ));
4950 }
50- dp_subtree[now] = g (ch, now);
51+ dp_subtree[now] = add_vertex (ch, now);
5152 }
5253
53- std::vector<Ch > left;
54+ std::vector<Children > left;
5455 for (int now : visorder) {
5556 int m = int (to[now].size ());
5657 left.assign (m + 1 , e ());
5758 for (int j = 0 ; j < m; j++) {
5859 int nxt = to[now][j].first ;
59- const St &st = (nxt == par[now] ? dp_par[now] : dp_subtree[nxt]);
60- left[j + 1 ] = merge (left[j], f (st, nxt, to[now][j].second ));
60+ const Subtree &st = (nxt == par[now] ? dp_par[now] : dp_subtree[nxt]);
61+ left[j + 1 ] = rake (left[j], add_edge (st, nxt, to[now][j].second ));
6162 }
62- dpall[now] = g (left.back (), now);
63+ dpall[now] = add_vertex (left.back (), now);
6364
64- Ch rprod = e ();
65+ Children rprod = e ();
6566 for (int j = m - 1 ; j >= 0 ; --j) {
6667 int nxt = to[now][j].first ;
67- if (nxt != par[now]) dp_par[nxt] = g ( merge (left[j], rprod), now);
68+ if (nxt != par[now]) dp_par[nxt] = add_vertex ( rake (left[j], rprod), now);
6869
69- const St &st = (nxt == par[now] ? dp_par[now] : dp_subtree[nxt]);
70- rprod = merge ( f (st, nxt, to[now][j].second ), rprod);
70+ const Subtree &st = (nxt == par[now] ? dp_par[now] : dp_subtree[nxt]);
71+ rprod = rake ( add_edge (st, nxt, to[now][j].second ), rprod);
7172 }
7273 }
7374 }
@@ -78,7 +79,7 @@ struct rerooting {
7879 }
7980 }
8081
81- const St &get_subtree (int root_, int par_) const {
82+ const Subtree &get_subtree (int root_, int par_) const {
8283 if (par_ < 0 ) return dpall.at (root_);
8384 if (par.at (root_) == par_) return dp_subtree.at (root_);
8485 if (par.at (par_) == root_) return dp_par.at (par_);
@@ -87,13 +88,13 @@ struct rerooting {
8788};
8889/* Template:
8990struct Subtree {};
90- struct Child {};
91+ struct Children {};
9192struct Edge {};
92- Child e() { return Child (); }
93- Child merge(Child x, Child y) { return Child (); }
94- Child f (Subtree x, int ch_id, Edge edge) { return Child (); }
95- Subtree g(Child x, int v_id) { return Subtree(); }
93+ Children e() { return Children (); }
94+ Children rake(Children x, Children y) { return Children (); }
95+ Children add_edge (Subtree x, int ch_id, Edge edge) { return Children (); }
96+ Subtree add_vertex(Children x, int v_id) { return Subtree(); }
9697
9798vector<vector<pair<int, Edge>>> to;
98- rerooting<Edge, Subtree, Child, merge, f, g , e> tree(to);
99+ rerooting<Edge, Subtree, Children, rake, add_edge, add_vertex , e> tree(to);
99100*/
0 commit comments