题解:CF1067E Random Forest Rank
::::info[“矩阵的秩”的定义]
即一个最大的
矩阵的秩的形式不太好,我们发现它在森林中其实等于最大匹配(考虑排列置换环要对应到树上只能长为
考虑树上最大匹配直接自底向上贪心,剩下直接用树形
::::info[DP 方法一]{open}
记
::::info[DP 方法二]{open}
将贡献拆成对每组匹配计数。记
这里给出方法二的实现:
#include <bits/stdc++.h>
#define FL(i, a, b) for (int i = (a); i <= (b); ++i)
#define FR(i, a, b) for (int i = (a); i >= (b); --i)
#define Sz(v) ((int)(v).size())
using namespace std;
typedef long long ll;
const int N = 5e5 + 10;
const int MOD = 998244353;
const int INV2 = (MOD + 1) / 2;
int n, f[N];
vector<int> G[N];
int Dfs(int u, int fa) {
int ret = 1;
for (int v: G[u]) {
if (v != fa) {
int t = Dfs(v, u);
f[u] = (f[u] + (ll)ret * t % MOD * INV2) % MOD;
ret = (ll)ret * (f[v] + 1) % MOD * INV2 % MOD;
}
}
return ret;
}
int main() {
scanf("%d", &n);
FL(i, 1, n - 1) {
int u, v;
scanf("%d %d", &u, &v);
G[u].emplace_back(v);
G[v].emplace_back(u);
}
Dfs(1, 0);
int ans = 0;
FL(i, 1, n) {
ans = (ans + f[i]) % MOD;
}
ans = (ll)ans * 2 % MOD;
FL(i, 1, n - 1) {
ans = ans * 2 % MOD;
}
printf("%d\n", ans);
return 0;
}