版权声明:本文为hzy原创文章,未经博主允许不可随意转载。 https://blog.csdn.net/Binary_Heap/article/details/81839405
题意
对一个 的二维方格涂上黑白两色,求至少 行全黑, 列全黑的方案数.
题解
可以先考虑行,然后考虑二维就十分简单了.
我们用 表示至少有 行全黑的方案数,容斥求一下:
因为是至少,所以需要容斥, 表示 行选 行, 表示其中剩下的行状态随意, 为容斥系数,我们需要递推出这个容斥系数.
每个行数为 的答案计算贡献只能算一次,所以:
因为 ,因此
用 和 的时间递推出行列的容斥系数 与 ,然后就可以得到答案的式子:
#include <cstdio>
const int MAXN = 3000;
const int MOD = 998244353;
int n, m, a, b;
int fa[MAXN + 10], fb[MAXN + 10];
int pow2[MAXN * MAXN + 10], c[MAXN + 10][MAXN + 10];
void init() {
pow2[0] = 1;
for(int i = 1; i <= MAXN * MAXN; i ++)
pow2[i] = (pow2[i - 1] * 2LL) % MOD;
for(int i = 0; i <= MAXN; i ++) {
c[i][0] = c[i][i] = 1;
for(int j = 1; j < i; j ++)
c[i][j] = (1ll * c[i-1][j-1] + c[i-1][j]) % MOD;
}
}
void calc_f() {
fa[a] = 1;
for(int i = a + 1; i <= n; i ++) {
fa[i] = 0;
for(int j = a; j < i; j ++)
fa[i] = (fa[i] + 1ll * c[i-1][j-1] * fa[j] % MOD) % MOD;
fa[i] = ((-fa[i]) % MOD + MOD) % MOD;
}
fb[b] = 1;
for(int i = b + 1; i <= m; i ++) {
fb[i] = 0;
for(int j = b; j < i; j ++)
fb[i] = (fb[i] + 1ll * c[i-1][j-1] * fb[j] % MOD) % MOD;
fb[i] = ((-fb[i]) % MOD + MOD) % MOD;
}
}
int main() {
init();
while(~ scanf("%d%d%d%d", &n, &m, &a, &b)) {
calc_f();
int ans = 0;
for(int i = a; i <= n; i ++)
for(int j = b; j <= m; j ++)
ans = (ans + 1ll * fa[i] * c[n][i] % MOD * fb[j] % MOD * c[m][j] % MOD * pow2[(n - i) * (m - j)] % MOD) % MOD;
printf("%d\n", (ans % MOD + MOD) % MOD);
}
return 0;
}