题解:AT_agc068_e [AGC068E] Sort and Match
bamboo12345 · · 题解
小清新。
题意:给出一个
做法:
首先考虑他是形如一个序列及其置换,所以我们考虑比如
我们思考如果随意拉一个欧拉回路麻烦的点在哪里,发现就是对于相同的
所以我们现在就只需要计算所有欧拉回路的权即可,我们枚举开始的位置是哪里,然后每次去拓展一条边即可,这个计算很简单。
然后最后还要做一次 dp 整合一下答案,直接就是对于长度
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 55 + 5, mod = 998244353;
int n, m, coef[maxn][maxn][maxn], s[maxn][maxn], ans[maxn], a[maxn][maxn];
int nw[maxn][maxn], dp[maxn][maxn];
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cin >> a[i][j];
for (int i = 1; i <= n; i++) {
memset(nw, 0, sizeof(nw));
nw[1][i] = 1;
for (int j = 1; j <= m; j++) {
for (int k = 1; k <= n; k++) {
coef[i][j][k] = (coef[i][j][k] + nw[j][k] * a[k][i]) % mod;
s[i][j] = (s[i][j] + nw[j][k] * a[k][i]) % mod;
for (int t = i + 1; t <= n; t++)
nw[j + 1][t] = (nw[j + 1][t] + nw[j][k] * a[k][t]) % mod;
// cout << i << " " << j << " " << k << " " << nw[j][k] << endl;
}
// cout << i << " " << j << " " << s[i][j] << endl;
}
}
for (int i = 1; i <= n; i++)
dp[m + 1][i] = 1;
for (int i = m; i >= 1; i--) {
for (int j = 1; j <= n; j++) {
if(i != 1) {
for (int k = 1; i + k <= m + 1; k++)
dp[i][j] = (dp[i][j] + dp[i + k][j] * s[j][k]) % mod;
}
else {
for (int k = 1; i + k <= m + 1; k++)
for (int t = j; t <= n; t++)
ans[t] = (ans[t] + dp[i + k][j] * coef[j][k][t]) % mod;
}
}
for (int j = n; j >= 1; j--)
dp[i][j] = (dp[i][j + 1] + dp[i][j]) % mod;
}
for (int i = 1; i <= n; i++)
cout << ans[i] << " ";
cout << endl;
return 0;
}