题意
对一个 n∗m n ∗ m 的二维方格涂上黑白两色,求至少 a a 行全黑,列全黑的方案数.
题解
可以先考虑行,然后考虑二维就十分简单了.
我们用 g(k) g ( k ) 表示至少有 k k 行全黑的方案数,容斥求一下:
因为是至少,所以需要容斥, Cin C n i 表示 n n 行选行, 2n−i 2 n − i 表示其中剩下的行状态随意, f(k) f ( k ) 为容斥系数,我们需要递推出这个容斥系数.
每个行数为 j j 的答案计算贡献只能算一次,所以:
∑ni=kf(i)∗Cin ∑ i = k n f ( i ) ∗ C n i
=∑n−1i=kf(i)∗Cin+f(n) = ∑ i = k n − 1 f ( i ) ∗ C n i + f ( n )
=∑n−1i=kf(i)∗(Ci−1n−1+Cin−1)+f(n) = ∑ i = k n − 1 f ( i ) ∗ ( C n − 1 i − 1 + C n − 1 i ) + f ( n )
=∑n−1i=k(f(i)∗Ci−1n−1+f(i)∗Cin−1)+f(n) = ∑ i = k n − 1 ( f ( i ) ∗ C n − 1 i − 1 + f ( i ) ∗ C n − 1 i ) + f ( n )
=1+∑n−1i=kf(i)∗Cin−1+f(n) = 1 + ∑ i = k n − 1 f ( i ) ∗ C n − 1 i + f ( n )
因为 ∑ni=kf(i)∗Cin=1 ∑ i = k n f ( i ) ∗ C n i = 1 ,因此 f(n)=−∑n−1i=kf(i)∗Ci−1n−1 f ( n ) = − ∑ i = k n − 1 f ( i ) ∗ C n − 1 i − 1
用 O(n2) O ( n 2 ) 和 O(m2) O ( m 2 ) 的时间递推出行列的容斥系数 fa f a 与 fb f b ,然后就可以得到答案的式子:
ans=∑ni=a∑mj=bfa(i)∗Cin∗fb(j)∗Cjm∗2(n−i)∗(m−j) a n s = ∑ i = a n ∑ j = b m f a ( i ) ∗ C n i ∗ f b ( j ) ∗ C m j ∗ 2 ( n − i ) ∗ ( m − j )
#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;
}