Hdu 4661 树上拓扑序计数
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN = 1000005; const int MAXM = 1000005; const int mod = 1e9 + 7; int to[MAXM << 1], nxt[MAXM << 1], Head[MAXN], ed = 1; inline void addedge(int u, int v) { to[++ed] = v; nxt[ed] = Head[u]; Head[u] = ed; } int T, n; ll dp[MAXN], sz[MAXN]; ll fac[MAXN], inv[MAXN]; ll anser = 0; ll Qpow(ll a, ll b) { ll ans = 1, base = a; while (b != 0) { if (b & 1 != 0) { ans *= base; ans %= mod; } base *= base; base %= mod; b >>= 1LL; } return ans; } void init() { fac[0] = 1; for (ll i = 1; i <= 1000000; i++) { fac[i] = fac[i - 1] * i % mod; } for (int i = 1; i <= 1000000; i++) { inv[i] = Qpow(fac[i], mod - 2); } } void getsz(int x, int fa) { sz[x] = 1; for (int v, i = Head[x]; i; i = nxt[i]) { v = to[i]; if (v == fa) { continue; } getsz(v, x); sz[x] += sz[v]; } return ; } void dp1(int x, int fa) { dp[x] = 1; for (int v, i = Head[x]; i; i = nxt[i]) { v = to[i]; if (v == fa) { continue; } dp1(v, x); dp[x] = ((dp[x] * dp[v]) % mod * inv[sz[v]]) % mod; } dp[x] = dp[x] * fac[sz[x] - 1] % mod; return ; } void dp2(int x, int fa) { if (x != 1) { //dp[x] = dp[fa] * sz[x] % mod * inv[n - sz[x]] % mod; dp[x] = dp[fa] * sz[x] % mod * Qpow(n - sz[x], mod - 2) % mod; anser = (anser + dp[x] * dp[x] % mod) % mod; } for (int v, i = Head[x]; i; i = nxt[i]) { v = to[i]; if (v == fa) { continue; } dp2(v, x); } return ; } int main() { init(); int u, v; scanf("%d", &T); while (T--) { anser = 0; scanf("%d", &n); ed = 1; for (int i = 1; i <= n; i++) { Head[i] = 0; } for (int i = 1; i < n; i++) { scanf("%d %d", &u, &v); addedge(u, v), addedge(v, u); } getsz(1, 0); dp1(1, 0); anser = dp[1] * dp[1] % mod; dp2(1, 0); anser += mod; anser %= mod; cout << anser << endl; } return 0; }