[ARC165E] Random Isolation 题解
首先这个操作次数看上去是和树的形态有关的,显然没法去求,考虑转化。对于每个大小大于
考虑如何由子树向上转移。我们考虑将期望选择的子树“剥离”出来。若这个子树有
代码:
#include <bits/stdc++.h>
#define N 205
#define int long long
#define mod 998244353
using namespace std;
int n, k;
int qpow(int x, int y) {
int ans = 1;
while (y) {
if (y & 1) ans = ans * x % mod;
x = x * x % mod;
y >>= 1;
}
return ans;
}
int fac[N], inv[N];
vector<int>v[N];
int dp[N][N][N];
int tmp[N][N];
int siz[N];
void add(int &x, int y) {
x = (x + y) % mod;
}
void dfs(int x, int fa) {
dp[x][1][0] = 1;
siz[x] = 1;
for (auto y : v[x]) {
if (y == fa) continue;
dfs(y, x);
dp[y][0][1] = 1;
memset(tmp, 0, sizeof tmp);
for (int j = 0; j <= siz[x]; j++)
for (int k = 0; k <= siz[x]; k++)
for (int p = 0; p <= siz[y]; p++)
for (int q = 0; q <= siz[y]; q++)
add(tmp[j + p][k + q], dp[x][j][k] * dp[y][p][q] % mod);
siz[x] += siz[y];
for (int j = 0; j <= siz[x]; j++)
for (int k = 0; k <= siz[x]; k++)
dp[x][j][k] = tmp[j][k];
}
}
int C(int n, int m) {
return fac[n] * fac[m] % mod * inv[n + m] % mod;
}
signed main() {
fac[0] = 1;
for (int i = 1; i < N; i++) fac[i] = fac[i - 1] * i % mod;
inv[N - 1] = qpow(fac[N - 1], mod - 2);
for (int i = N - 2; ~i; --i) inv[i] = inv[i + 1] * (i + 1) % mod;
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> k;
for (int i = 1; i < n; i++) {
int x, y;
cin >> x >> y;
v[x].push_back(y);
v[y].push_back(x);
}
dfs(1, 0);
int ans = 0;
for (int x = 1; x <= n; x++)
for (int i = k + 1; i <= siz[x]; i++)
for (int j = 0; j <= siz[x]; j++)
add(ans, dp[x][i][j] * C(i, j + (x != 1)) % mod);
cout << ans << "\n";
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律