51nod 1829 函数 (斯特林数)

来源:互联网 发布:软件产品质量缺陷等级 编辑:程序博客网 时间:2024/06/05 04:34

Description

想知道f:A->B这个函数(其中|A|=n, |B|=m)的所有映射关系要使B的每个元素都要被A的一个元素覆盖到。

数字可能很大你只要输出方案数模1,000,000,007即可。

 

Input

一共一行两个数,n和m。(1<=n,m<=1,000,000)

 

Output

一共一行包含一个方案数。

 

Input示例

2 2

 

Output示例

2

 

思路

原题相当于: n 个不同的球(定义域)放入 m 个不同的盒子(值域),盒子不可以为空,求总共的方案数。

答案: M!×S(N,M) ,其中 S 表示第二类斯特林数。

 

AC 代码

#include <bits/stdc++.h>using namespace std;typedef __int64 LL;const int maxn = 1e6+10;const int mod = 1e9+7;LL mul[maxn];LL inv[maxn];void init(){    mul[0]=1;    for(int i=1; i<maxn; i++)        mul[i]=(mul[i-1]*i)%mod;    inv[0]=inv[1]=1;    for(int i=2; i<maxn; i++)        inv[i]=(LL)(mod-mod/i)*inv[mod%i]%mod;    for(int i=1; i<maxn; i++)        inv[i]=(inv[i-1]*inv[i])%mod;}LL C(int n,int m){    return mul[n]*inv[m]%mod*inv[n-m]%mod;}LL mult(LL a,int n){    a%=mod;    LL ans = 1;    while(n)    {        if(n&1) ans = (ans*a)%mod;        a = (a*a)%mod;        n>>=1;    }    return ans;}int main(){    init();    int n,m;    cin>>n>>m;    LL ans = 0;    for(int i = 0,e = 1; i <= m; i++,e*=-1)        ans = (C(m,i) * mult(m-i,n) %mod * e + ans)%mod;    cout<<(ans+mod)%mod<<endl;    return 0;}
原创粉丝点击