hdu6314 容斥+数学
题意 : n*m的矩阵 可以涂黑白两色 问至少A行B列为黑色的涂色方案种类数,答案对998244353取模,1<=n,m,A,B<=3000
题解: ans=sum{A,..n}sum(B,...m}*f[n-i][m-j] (i,j分别为前两个∑的迭代变量),f[a][b]表示a行b列中没有一行或者一列全部涂黑
由容斥定理 f[i][j]=sum{0,..i}sum{0,.j}*(-1)(a+b)*2(i-a)*(j-b) (a,b分别为前两个∑的迭代变量)。
代入得ans=sum{A,...n}sum{B,...m}sum{0,....n-i}sum{0,...m-j} n!m!(-1)a+b2(n-i-a)(m-j-b) /((n-i-a)!(m-j-b)!i!j!a!b!) (i,j,a,b)分别∑为的迭代变量
#include<cstdio> using namespace std; const int P=998244353; const int N=3e3+7; int e[N*N],fac[N],facn[N*N],pre[N][N],g[N][N]; inline int ksm(int x,int k){ int ans=1; for(;k;k>>=1,x=1LL*x*x%P) if(k&1) ans=1LL*ans*x%P; return ans; } void init(){ int i,val; for(e[0]=i=1;i<=9000000;++i) e[i]=2LL*e[i-1]%P; for(fac[0]=facn[0]=i=1;i<=3000;++i) fac[i]=1LL*i*fac[i-1]%P,facn[i]=ksm(fac[i],P-2); for(int i=0;i<=3000;++i) for(int j=i;j>=0;--j) { val=1LL*facn[j]*facn[i-j]%P; if((i-j)&1) val=P-val; pre[i][j]=(val+pre[i][j+1])%P; } for(int i=0;i<=3000;++i) for(int j=0;j<=3000;++j) g[i][j]=1LL*e[i*j]*facn[i]%P*facn[j]%P; } int main(){ init(); int n,m,A,B; while(~scanf("%d%d%d%d",&n,&m,&A,&B)){ int ans=0; for(int i=0;i<=n-A;++i) for(int j=0;j<=m-B;++j) ans=(ans+1LL*pre[n-i][A]*pre[m-j][B]%P*g[i][j]%P)%P; printf("%d\n",1LL*ans*fac[n]%P*fac[m]%P); } }