Fishing alone trees and snow
Topic links : https://www.lydsy.com/JudgeOnline/problem.php?id=3162
Problem solution :
First, without the same restrictions essence this is a sucker title.
Dp like tree directly.
So if you coupled with the restriction?
We found that no matter how final the same nature, the center of gravity of the tree must be invariant.
Therefore, the focus began to go heavy.
Reference : https: //www.cnblogs.com/zhoushuyu/p/9295759.html
Code :
#include <bits/stdc++.h> #define N 500010 using namespace std; const int mod = 1000000007 ; char *p1, *p2, buf[100000]; typedef unsigned long long ll; ll bs1 = 20021214 ; ll bs2 = 20030315 ; #define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ ) int rd() { int x = 0; char c = nc(); while (c < 48) { c = nc(); } while (c > 47) { x = (((x << 2) + x) << 1) + (c ^ 48), c = nc(); } return x; } int n, inv[N], to[N << 1], nxt[N << 1], head[N], tot, sz[N], w[N], root, rt1, rt2, flag, f[2][N], tmp[N]; ll hs[N]; inline void add(int x, int y) { to[ ++ tot] = y; nxt[tot] = head[x]; head[x] = tot; } void getroot(int p, int fa) { sz[p] = 1; w[p] = 0; for (int i = head[p]; i; i = nxt[i]) { if(to[i] != fa) { getroot(to[i], p); sz[p] += sz[to[i]]; w[p] = max(w[p], sz[to[i]]); } } w[p] = max(w[p], n - sz[p]); if (w[p] < w[root]) { root = p; } } int C(int n, int m) { int re = 1; for (int i = n - m + 1; i <= n; i ++ ) { re = (ll)re * i % mod; } for (int i = 1; i <= m; i ++ ) { re = (ll)re * inv[i] % mod; } return re; } inline bool cmp(int i, int j) { return hs[i] < hs[j]; } void dfs(int p, int fa) { sz[p] = f[0][p] = f[1][p] = 1; for (int i = head[p]; i; i = nxt[i]) { if (to[i] != fa) { dfs(to[i], p); sz[p] += sz[to[i]]; } } int len = 0; for (int i = head[p]; i; i = nxt[i]) { if (to[i] != fa) { tmp[ ++ len] = to[i]; } } sort(tmp + 1, tmp + len + 1, cmp); for (int i = 1, j = 1; i <= len; i = j) { while (j <= len && hs[tmp[j]] == hs[tmp[i]]) { j ++ ; } f[0][p] = (ll)f[0][p] * C(f[0][tmp[i]] + f[1][tmp[i]] + j - i - 1, j - i) % mod; f[1][p] = (ll)f[1][p] * C(f[0][tmp[i]] + j - i - 1, j - i) % mod; } hs[p] = bs2 * len + sz[p]; for (int i = 1; i <= len; i ++ ) { hs[p] = (hs[p] * bs1) ^ hs[tmp[i]]; } } int main() { n = rd(); inv[0] = inv[1] = 1; for (int i = 2; i <= n; i ++ ) { inv[i] = (ll)inv[mod % i] * (mod - mod / i) % mod; } for (int i = 1; i < n; i ++ ) { int x = rd(), y = rd(); add(x, y), add(y, x); } w[0] = n; getroot(1, 0); getroot(root, 0); for (int i = head[root], last = 0; i; last = i, i = nxt[i]) { if (sz[to[i]] * 2 == n) { n ++ ; if (i == head[root]) { head[root] = nxt[i]; } else { nxt[last] = nxt[i]; } for (int j = head[to[i]], lst = 0; j; lst = j, j = nxt[j]) { if (to[j] == root) { if (j == head[to[i]]) { head[to[i]] = nxt[j]; } else { nxt[lst] = nxt[j]; } break; } } add(n, root); add(root, n); add(n, to[i]); add(to[i], n); rt1 = root; rt2 = to[i]; root = n; flag = 1; break; } } dfs(root, 0); if (!flag) { cout << (f[0][root] + f[1][root]) % mod << endl ; } else if (hs[rt1] == hs[rt2]) { cout << (f[0][root] - C(f[1][rt1] + 1, 2) + mod) % mod; } else { cout << ((ll)f[0][rt1] * f[0][rt2] + (ll)f[0][rt1] * f[1][rt2] + (ll)f[1][rt1] * f[0][rt2]) % mod << endl ; } }
Summary : tree hash of the time, if a module to worry about trouble, like me, like two open 233