本题有一点难度!这里运用了数论知识。还有要记住一个公式:
题意其实就等同于将n个不同的球放进k个相等的盒子中,也就是第二类斯特林数。,
题目数据n给的那么大没什么,主要在k那里埋下了一个重大的坑啊! k<=9的时候所有的数据都能跑过,但当k等于10的时候10!*2007>10^10。 那么在模幂运算的时候d=d*t%m,d*t已经超过了long long的数据范围,那么在做乘法越界的情况下,就将乘转化为(加、减)取模运算。
其中记住:(a/b)%m=(a%(b*m))/b.
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <cstdio>
#include <cmath>
#include <string>
#include <stack>
#include <cctype>
using namespace std;
int FF(__int64 n)
{
if(n%2==0)
return 1;
else
return -1;
}
__int64 Cm_i(__int64 m,__int64 i)
{
__int64 a[15];
a[0]=1;
a[1]=1;
for(__int64 i=2; i<=10; i++)
{
a[i]=a[i-1]*i;
}
return a[m]/(a[i]*a[m-i]);
}
__int64 mul_mod(__int64 a,__int64 b,__int64 m)
{
__int64 ans=0;
__int64 d=a%m;
while(b)
{
if(b&1)
ans=ans+d;
if(ans>=m)
ans-=m;
d<<=1;
if(d>=m)
d-=m;
b>>=1;
}
return ans;
}
__int64 pow_mod(__int64 a,__int64 r,__int64 m)
{
__int64 d=1,t=a%m;
while(r)
{
if(r%2)
d=mul_mod(d,t,m);
r/=2;
t=mul_mod(t,t,m)%m;
}
return d%m;
}
int main()
{
__int64 n,k;
__int64 a[15];
a[0]=1;
a[1]=1;
for(__int64 i=2; i<=10; i++)
{
a[i]=a[i-1]*i;
}
while(~scanf("%I64d%I64d",&n,&k))
{
__int64 sum=0;
__int64 m=a[k]*2007;
for(__int64 j=0; j<=k-1; j++)
{
//printf("%d\n",Cm_i(k,j));
sum+=FF(j)*pow_mod(k-j,n,m)*Cm_i(k,j);
sum=(sum%m+m)%m;
}
sum=sum%m/a[k];
printf("%I64d\n",sum);
}
return 0;
}