题目描述:
华华在和秀秀视频时有截很多图。华华发现秀秀的每一张照片都很萌很可爱。为什么会这
样呢?华华在仔细看过秀秀的所有照片后,发现秀秀的照片都具有一个相同的性质。
设秀秀的分辨率为?×?,即在水平方向上每一行有?个像素,垂直方向上每一列有?个像
素,照片共有?×?个像素。每一个像素都有一个颜色,共有?种颜色。华华宝宝发现无论是沿
着哪两列像素的分界线将秀秀的照片分成左右两半(共有? − 1种分法),左右两半不同颜色的
种数都是相同的。
华华宝宝把自己的发现告诉了秀秀宝宝。现在秀秀想知道当照片分辨率为?×?,像素颜色
种数为?(不一定?种颜色都出现)的时候,共有多少张不同的照片满足上面的性质。
由于答案可能很大,你只需输出答案对1000000007(10. + 7)取模的结果即可。
输入:
输入共一行,包含三个正整数?,?, ?。
输出:
输出共一行,输出答案对10. + 7取模的结果。
算法标签:大力推式子,strling数
思路:
i表示两边选几个,j表示公共选几个,S是strling数。中间平方的部分是把n个不同球放到m个不同篮子的方案数。
第二类strling递推公式:
cc[1][1]=1;cc[0][0]=0;for(int i=1;i<=n;i++)cc[i][i]=1,cc[i][0]=0; for(int i=2;i<=n;i++)for(int j=1;j<=i;j++) cc[i][j]=mu(cc[i-1][j-1]+cc[i-1][j]*(LL)j%p);
以下代码:
#include<bits/stdc++.h> #define il inline #define LL long long #define _(d) while(d(isdigit(ch=getchar()))) using namespace std; const int p=1e9+7,N=3005,K=1e6+5;int n,m,k;LL jc[K],ny[K],ans,tt[N],cc[N][N]; il int read(){int x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch^48;_()x=(x<<1)+(x<<3)+(ch^48);return f*x;} il LL ksm(LL a,int y){LL b=1;while(y){if(y&1)b=b*a%p;a=a*a%p;y>>=1;}return b;} il LL mu(LL a){if(a>=p)return a-p;return a;} il LL C(int n,int m){if(n<m)return 0;return jc[n]*ny[m]%p*ny[n-m]%p;} int main() { n=read();m=read();k=read();int kk=max(n,k); jc[0]=1;for(int i=1;i<=kk;i++)jc[i]=jc[i-1]*(LL)i%p;ny[kk]=ksm(jc[kk],p-2); for(int i=kk;i;i--)ny[i-1]=ny[i]*(LL)i%p; if(m==1){printf("%lld",ksm((LL)n,k));return 0;} cc[1][1]=1;cc[0][0]=0;for(int i=1;i<=n;i++)cc[i][i]=1,cc[i][0]=0; for(int i=2;i<=n;i++)for(int j=1;j<=i;j++) cc[i][j]=mu(cc[i-1][j-1]+cc[i-1][j]*(LL)j%p); for(int i=0;i<=n;i++)tt[i]=ksm((LL)i,(m-2)*n); for(int i=1;i<=min(n,k);i++){ LL res=0; for(int j=0;j<=i;j++){ res=mu(res+tt[j]*C(i,j)%p*C(k-i,i-j)%p); } ans=mu(ans+res*C(k,i)%p*cc[n][i]%p*jc[i]%p*cc[n][i]%p*jc[i]%p); } printf("%lld\n",ans); return 0; }