彼方へ、名もなき海辺より
Mier_Samuelle · · 题解
:::info[记号]{open}
:::
手玩几个样例可发现,连通块的个数就是环的个数。考虑什么时候会形成环,要是
:::align{center}
如图,
:::
考虑在
整理得
暴力是
若
这样便可用一次遍历求出所有
:::success[Code]{open}
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 5e5 + 10;
const int MOD = 998244353;
vector <int> adj[MAXN];
int deg[MAXN], dep[MAXN], inv[MAXN], w[MAXN], f[MAXN], n;
int qpow(int x, int y){
int res = 1;
while (y){
if (y & 1){
res = res * x % MOD;
}
x = x * x % MOD;
y >>= 1;
}
return res;
}
void dfs(int u, int fa){
dep[u] = dep[fa] + 1;
if (dep[u] == 1){
w[u] = dep[u] + deg[u] - 1;
}
else{
w[u] = dep[u] + deg[u] - 2;
}
inv[u] = qpow(w[u], MOD - 2);
f[u] = (f[fa] * inv[u] % MOD + inv[u] * inv[fa] % MOD) % MOD;
for (int v : adj[u]){
if (v == fa){
continue;
}
dfs(v, u);
}
return;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
for (int i = 1; i < n; i++){
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
deg[u]++;
deg[v]++;
}
dfs(1, 0);
int mul = 1, sum = 0;
for (int i = 1; i <= n; i++){
mul = mul * w[i] % MOD;
sum = (sum + f[i]) % MOD;
}
cout << mul * sum % MOD << "\n";
return 0;
}
:::