【数学】U168701 “基本”数学问题

ORZZJY!

去年暑假,我被 JohnJoeZhu 的这道题吊打。

现在,我已经能一眼了()

好吧,事实上就是个二维二项式反演的板子。

容易发现 \(x\)\(y\) 列是啥没影响。

考虑设 \(f[i][j]\) 为至少有 \(i\) 行关键行 \(j\) 列关键列未染色的情况数。为什么不设为染色呢,因为难表示。\(g[i][j]\) 为恰好的。答案就是 \(g[0][0]\)

显然

\[f[i][j]=\binom{x}{i}\binom{y}{j}\binom{nm-tot}{k},tot=im+jn-ij \]

\[f[i][j]=\sum_{a=i}^x\sum_{b=j}^y\binom{a}{i}\binom{b}{j}g[a][b] \]

\[g[0][0]=\sum_{i=0}^x\sum_{j=0}^m(-1)^{i+j}f[i][j] \]

#include <bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
int rd() {
    int f=1,sum=0; char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) {sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    return sum*f;
}
#define N 1005
#define M (int)(1e6+5)
const int mod=998244353;
int fpow(int x,int y) {
	int res=1; x%=mod;
	while(y) {
		if(y&1) res=res*x%mod;
		y>>=1; x=x*x%mod;
	}
	return res;
}
int f[N][N],jie[M],djie[M],n,m,x,y,k;

int C(int n,int m) {
	if(m>n||m<0||n<0) return 0;
	return jie[n]*djie[m]%mod*djie[n-m]%mod;
}

signed main() {
	jie[0]=1; for(int i=1;i<=M-5;i++) jie[i]=jie[i-1]*i%mod;
	djie[M-5]=fpow(jie[M-5],mod-2);
	for(int i=M-5;i;i--) djie[i-1]=djie[i]*i%mod;
	n=rd(); m=rd(); k=rd(); x=rd(); y=rd();
	for(int i=0;i<=x;i++) {
		for(int j=0;j<=y;j++) {
			int tot=i*m+j*n-i*j;
			f[i][j]=C(x,i)*C(y,j)%mod*C(n*m-tot,k)%mod;
		}
	}
	int ans=0;
	for(int i=0;i<=x;i++) {
		for(int j=0;j<=y;j++) {
			ans=(ans+(((i+j)&1)?-1:1)*f[i][j]%mod)%mod;
		}
	}
	ans=(ans%mod+mod)%mod;
	printf("%lld",ans);
	return 0;
} 
posted @ 2022-02-08 17:59  FxorG  阅读(46)  评论(0编辑  收藏  举报