A 送你一道签到题 (Unaccepted)
题目大意 :
- 咕咕
Code
Show Code
B 神犇 (Unaccepted)
题目大意 :
- 咕咕
Code
Show Code
C 开挂
题目大意 : 有多少组nm的01矩阵用两个xy的矩阵完全覆盖
-
枚举01矩阵的最小范围,dp的时候有6维,前4维是4边有没有1,第5维是1不在左上右下的情况里的覆盖范围,第6维是1不在左下右上的情况覆盖范围
-
因为是枚举的边界,前4维都是必须满足的,而5,6维只要有1就合法
-
然后就是这题卡常
Code
Show Code
#include <cstdio>
#include <cstring>
using namespace std;
const int M = 998244353;
int n, m, x, y, f[2][64], ans = 1;
void Add(int &x, int y) {
if ((x += y) >= M) x -= M;
}
int Solve(int n, int m) {
int k = 0;
memset(f[k], 0, 64 * 4);
f[k][0] = 1;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
memset(f[k^=1], 0, 64 * 4);
for (int s = 0; s < 64; ++s)
Add(f[k][s], f[k^1][s]), Add(f[k][s|(i==1)<<5|(i==n)<<4|(j==1)<<3|(j==m)<<2|
(!(i <= x && j <= y) && !(i+x > n && j+y > m)) << 1 | (!(i <= x && j+y > m) && !(i+x > n && j <= y))], f[k^1][s]);
}
}
return (1ll * f[k][60] + f[k][61] + f[k][62]) % M;
}
int main() {
scanf("%d%d%d%d", &n, &m, &x, &y);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
if ((ans += 1ll * (n - i + 1) * (m - j + 1) % M * Solve(i, j) % M) >= M) ans -= M;
printf("%d
", ans);
return 0;
}