题解:AT_abc327_g [ABC327G] Many Good Tuple Problems
Egg_eating_master · · 题解
设
对于
对于
算答案时枚举本质不同的边的数量,容斥一下即可。
时间复杂度
::::info[代码]
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 35, mod = 998244353;
int n, m;
int dp[maxn][maxn * maxn][maxn];
int c[maxn * maxn][maxn * maxn];
int ans;
int power(int a, int b) {
int res = 1;
while (b) {
if (b & 1) res = res * a % mod;
a = a * a % mod; b >>= 1;
}
return res;
}
void init(int n) {
for (int i = 0; i <= n; i++) {
c[i][0] = 1;
for (int j = 1; j <= i; j++) c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
}
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> m; init(n * n);
dp[1][0][1] = 1;
for (int i = 2; i <= n; i++)
for (int j = 0; j <= i * (i - 1) / 2; j++) {
for (int k = 2; k <= i; k++)
for (int x = 1; x < i; x++)
for (int y = 0; y <= j; y++)
dp[i][j][k] = (dp[i][j][k] + dp[x][y][1] * dp[i - x][j - y][k - 1] % mod * c[i - 1][x - 1]) % mod;
for (int x = 1; x < i; x++) dp[i][j][1] = (dp[i][j][1] + c[x * (i - x)][j] * c[i][x]) % mod;
for (int x = 2; x <= i; x++) dp[i][j][1] = (dp[i][j][1] - dp[i][j][x] * power(2, x)) % mod;
dp[i][j][1] = (mod + 1) / 2 * dp[i][j][1] % mod;
if (i - j > 1) dp[i][j][1] = 0;
}
for (int i = 1; i <= min(m, n * (n - 1) / 2); i++) {
int sum = 0;
for (int j = 1; j <= n; j++) sum = (sum + dp[n][i][j]) % mod;
for (int j = 0; j <= i; j++) {
int s = c[i][j] * power(2 * j, m) % mod * sum % mod;
if ((i - j) & 1) ans = (ans - s) % mod;
else ans = (ans + s) % mod;
}
}
cout << (ans + mod) % mod << '\n';
return 0;
}
::::