2018.10.30-dtoj-4010-秀秀的照片(photo)

题目描述:

华华在和秀秀视频时有截很多图。华华发现秀秀的每一张照片都很萌很可爱。为什么会这
样呢?华华在仔细看过秀秀的所有照片后,发现秀秀的照片都具有一个相同的性质。
设秀秀的分辨率为𝑚×𝑛,即在水平方向上每一行有𝑚个像素,垂直方向上每一列有𝑛个像
素,照片共有𝑚×𝑛个像素。每一个像素都有一个颜色,共有𝑘种颜色。华华宝宝发现无论是沿
着哪两列像素的分界线将秀秀的照片分成左右两半(共有𝑚 − 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);
View Code

 

以下代码:

#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;
}
View Code

 

posted @ 2018-10-30 17:20  Jessiejzy  阅读(319)  评论(0编辑  收藏  举报