比赛的时候, 用了一种垃圾树hash,没过去。。
#pragma GCC optimize(2) #pragma GCC optimize(3) #include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ALL(x) (x).begin(), (x).end() #define fio ios::sync_with_stdio(false); cin.tie(0); #define ll long long using namespace std; const int N = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; const double eps = 1e-8; const double PI = acos(-1); template<class T, class S> inline void add(T &a, S b) {a += b; if(a >= mod) a -= mod;} template<class T, class S> inline void sub(T &a, S b) {a -= b; if(a < 0) a += mod;} template<class T, class S> inline bool chkmax(T &a, S b) {return a < b ? a = b, true : false;} template<class T, class S> inline bool chkmin(T &a, S b) {return a > b ? a = b, true : false;} mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); const ull B = 1000000007; int n, m, p, id[N]; int F[N], Finv[N], inv[N]; int way[N], totway[N]; ull sz[N]; ull hsson[N]; ull hstot[N]; ull Pow[N]; ull rnd[N]; int Rt = 1; int depth[N]; vector<pair<ull, int>> V[N]; vector<int> G[N]; void dfs(int u, int fa) { way[u] = 1; hsson[u] = 0; sz[u] = 1; depth[u] = depth[fa] + 1; for(int i = 0; i < SZ(G[u]); i++) { if(G[u][i] == fa) { G[u].erase(G[u].begin() + i); break; } } for(auto &v : G[u]) { dfs(v, u); V[u].push_back(mk(hsson[v], v)); way[u] = 1LL * way[u] * way[v] % mod; sz[u] += sz[v]; } sort(ALL(V[u])); for(auto &t : V[u]) { hsson[u] = hsson[u] * Pow[sz[t.se]] + t.fi; } hsson[u] = hsson[u] * B + rnd[sz[u]]; way[u] = 1LL * way[u] * F[SZ(V[u])] % mod; for(int i = 0, j = 0; i < SZ(V[u]); i = j) { while(j < SZ(V[u]) && V[u][j].fi == V[u][i].fi) j++; way[u] = 1LL * way[u] * Finv[j - i] % mod; } } void dfs2(int u, ull fhs, int fway) { int divway = 1; int mulway = 1; if(u != Rt) { V[u].push_back(mk(fhs, 0)); } for(int i = SZ(V[u]) - 1; i > 0; i--) { if(V[u][i] < V[u][i - 1]) swap(V[u][i], V[u][i - 1]); } hstot[u] = 0; totway[u] = 1; for(auto &t : V[u]) { if(t.se) { totway[u] = 1LL * totway[u] * way[t.se] % mod; hstot[u] = hstot[u] * Pow[sz[t.se]] + t.fi; } else { totway[u] = 1LL * totway[u] * fway % mod; hstot[u] = hstot[u] * Pow[n - sz[u]] + t.fi; } } totway[u] = 1LL * totway[u] * F[SZ(V[u])] % mod; hstot[u] = hstot[u] * B + rnd[n]; vector<int> cnt(SZ(V[u])); for(int i = 0, j = 0; i < SZ(V[u]); i = j) { while(j < SZ(V[u]) && V[u][j].fi == V[u][i].fi) j++; totway[u] = 1LL * totway[u] * Finv[j - i] % mod; divway = 1LL * divway * Finv[j - i] % mod; for(int k = i; k < j; k++) { cnt[k] = j - i; } } mulway = F[SZ(V[u]) - 1]; vector<pair<ull, int>> pre(SZ(V[u])); vector<pair<ull, int>> suf(SZ(V[u])); vector<int> sufsz(SZ(V[u]) + 1, 0); ull tmphs = 0; int tmpway = 1; int tmpsz = 0; for(int i = 0; i < SZ(V[u]); i++) { if(V[u][i].se) { tmpway = 1LL * tmpway * way[V[u][i].se] % mod; tmphs = tmphs * Pow[sz[V[u][i].se]] + V[u][i].fi; } else { tmpway = 1LL * tmpway * fway % mod; tmphs = tmphs * Pow[n - sz[u]] + V[u][i].fi; } pre[i] = mk(tmphs, tmpway); } tmphs = 0; tmpway = 1; tmpsz = 0; for(int i = SZ(V[u]) - 1; i >= 0; i--) { if(V[u][i].se) { tmpway = 1LL * tmpway * way[V[u][i].se] % mod; tmphs += Pow[tmpsz] * V[u][i].fi; tmpsz += sz[V[u][i].se]; } else { tmpway = 1LL * tmpway * fway % mod; tmphs += Pow[tmpsz] * V[u][i].fi; tmpsz += n - sz[u]; } suf[i] = mk(tmphs, tmpway); sufsz[i] = tmpsz; } for(int i = 0; i < SZ(V[u]); i++) { if(V[u][i].se == 0) continue; tmphs = 0, tmpway = 1; if(i + 1 < SZ(V[u])) { tmphs = suf[i + 1].fi; tmpway = 1LL * tmpway * suf[i + 1].se % mod; } if(i) { tmphs += pre[i - 1].fi * Pow[sufsz[i + 1]]; tmpway = 1LL * tmpway * pre[i - 1].se % mod; } tmphs = tmphs * B + rnd[n - sz[V[u][i].se]]; tmpway = 1LL * tmpway * mulway % mod; tmpway = 1LL * tmpway * divway % mod; tmpway = 1LL * tmpway * F[cnt[i]] % mod; tmpway = 1LL * tmpway * Finv[cnt[i] - 1] % mod; dfs2(V[u][i].se, tmphs, tmpway); } } void init() { for(int i = 1; i <= n; i++) { G[i].clear(); V[i].clear(); } } int main() { F[0] = Finv[0] = inv[1] = Pow[0] = 1; for(int i = 1; i < N; i++) { Pow[i] = Pow[i - 1] * B; } for(int i = 2; i < N; i++) { inv[i] = 1LL * (mod - mod / i) * inv[mod % i] % mod; } for(int i = 1; i < N; i++) { F[i] = 1LL * F[i - 1] * i % mod; } for(int i = 1; i < N; i++) { Finv[i] = 1LL * Finv[i - 1] * inv[i] % mod; } for(int i = 1; i < N; i++) { rnd[i] = rng(); } int T; scanf("%d", &T); while(T--) { scanf("%d", &n); init(); for(int i = 1; i <= n; i++) { id[i] = i; } for(int i = 1; i < n; i++) { int u, v; scanf("%d%d", &u, &v); G[u].push_back(v); G[v].push_back(u); } dfs(Rt, 0); dfs2(Rt, 0, 1); sort(id + 1, id + 1 + n, [&](int A, int B) { return hstot[A] < hstot[B]; }); int ans = 0; for(int i = 1; i <= n; i++) { if(i == 1 || hstot[id[i]] != hstot[id[i - 1]]) { add(ans, totway[id[i]]); } } printf("%d ", ans); } return 0; } /* */