// output[r] = dp[r], where dp[v] := // fin(Sum_{child c of v, regarding root r} fromChild( dp[c] )) // To remove weights, remove every "w" and "W" and fix errors struct Reroot { using D = /*todo*/; // dp value using A = /*todo(often D)*/; //value from a vertex's child(ren) //(A,agg,e) commutative monoid A e = /*todo*/; A fromChild(int v, int c, auto w, D dp_c) { /*todo*/ } static A agg(A a, A b) { /*todo*/ } D fin(int v, A chilsAgg) { /*todo*/ } vector dp; D dfs0(auto& g, int v, int from = -1) { A ca = e; for (auto [c, w] : g[v]) { if (c == from) continue; ca = agg(ca, fromChild(v, c, w, dfs0(c, v, g))); } return dp[v] = fin(v, ca); } void dfs1(auto& g, int v, int from = -1) { vector ps = {e}; for (auto [c, w] : g[v]) { ps.push_back(fromChild(v, c, w, dp[c])); } auto ss = ps; exclusive_scan(be(ps), ps.begin(), e, agg); exclusive_scan(ss.rbegin(), ss.rend(), ss.rbegin(), e, agg); int i = 0; for (auto [c, w] : g[v]) { ++i; if (c == from) continue; dp[v] = fin(v, agg(ss[i], ps[i])); dfs1(c, v, g); } dp[v] = fin(v, ss[0]); } template auto solve(vector>> g) { dp.resize(sz(g)); dfs0(g, 0); dfs1(g, 0); return dp; } };