BSOJ4125题解

行列都互不相同,这也太麻烦了!

考虑去掉行或列的限制,然后使用反演。

考虑只有行互不相同的 \(n\times m\) 的矩阵数量为 \(f[n][m]\),显然有:

\[f[n][m]=(c^m)^{\underline n} \]

发现考虑列的时候,由于行之间一定互不相同,所以不需要去考虑行了。

考虑 \(g[n][m]\) 为所求,要先使用 \(g\) 去演绎 \(f\) 才有可能得到反演的柿子。

此时 \(n\) 已无意义,因为行之间已经互不相同了。于是枚举列的数量表示有这么多个列互不相同。

容易发现相当于是让每一列选择一列 \(g\) 中的,得到演绎柿:

\[f[n][m]=\sum_{i=1}^{m}\begin{Bmatrix}m\\i\end{Bmatrix}g[n][i] \]

使用斯特林反演有:

\[g[n][m]=\sum_{i=1}^{m}\begin{bmatrix}m\\i\end{bmatrix}(-1)^{m-i}f[n][i] \]

直接算,\(O(m^2)\)

#include<cstdio>
const int M=4005,mod=1e9+7;
int n,m,c,S1[M];
signed main(){
	int sum(0);scanf("%d%d%d",&n,&m,&c);
	S1[0]=1;for(int i=1;i<=m;++i){for(int j=i;j>=1;--j)S1[j]=((i-1ll)*S1[j]+S1[j-1])%mod;S1[0]=0;}
	for(int t(c),i=1;i<=m;++i,t=1ll*t*c%mod){
		int prod(1);for(int k=0;k<n;++k)prod=1ll*prod*(mod+t-k)%mod;sum=(sum+1ll*(m-i&1?mod-S1[i]:S1[i])*prod)%mod;
	}
	printf("%d",sum);
}
posted @ 2022-07-20 15:15  Prean  阅读(15)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};