http://codeforces.com/problemset/problem/852/E
初全方位木DPです。
観察するとGood Moodになる方法とBad Moodになる方法は同じ数だけあります。なのでGood Moodのみ考えれば良くて、
全方位木DPをすれば簡単に求められます。
全方位木DPについてですが、これは簡単で木から1つ子を除いた場合を考えて根からdfsするだけです。
int N; vector<int> E[MAX_N]; ll g[MAX_N]; ll G[MAX_N]; int ts[MAX_N]; ll mod_pow(ll a, ll n) { if(n == 0) return 1; ll res = mod_pow(a, n / 2); if(n % 2 == 0) return res * res % mod; else return a * res % mod * res % mod; } ll invf(ll a) { return mod_pow(a, mod - 2); } ll dfs1(int v, int p) { ll res = 1; ts[v] = 1; bool found = false; rep(i, 0, sz(E[v])) { int n = E[v][i]; if(n == p) continue; MUL(res, dfs1(n, v)); ts[v] += ts[n]; found = true; } if(!found) return g[v] = 1; else return g[v] = 2 * res % mod; } void dfs2(int v, int p, ll pv) { // debug(v, p, pv); G[v] = 2; rep(i, 0, sz(E[v])) { int n = E[v][i]; if(n == p) MUL(G[v], pv); else MUL(G[v], g[n]); } rep(i, 0, sz(E[v])) { int n = E[v][i]; if(n == p) continue; if(ts[n] == N - 1) dfs2(n, v, 1); else dfs2(n, v, G[v] * invf(g[n]) % mod); } } void solve() { cin >> N; if(N == 1) { cout << 1 << "\n"; return; } rep(i, 0, N - 1) { int a, b; cin >> a >> b; a--; b--; E[a].pb(b); E[b].pb(a); } dfs1(0, -1); dfs2(0, -1, 1); ll ans = 0; // debug(vi(g, g + N)); // debug(vi(G, G + N)); rep(i, 0, N) ADD(ans, G[i]); cout << ans << "\n"; }
テストケースが12個しかないんですがこれは大丈夫なんですかね…