代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn = 1e6+5;
ll f[maxn], fac[maxn];
ll pow(ll a, ll b) { //快速幂取模
ll ret = 1;
while(b) {
if(b&1)
ret = (ret*a)%mod;
a = (a*a)%mod;
b>>=1;
}
return ret;
}
int main()
{
ll n, k;
cin>>n>>k;
for(int i = 1; i<=k+2; i++) { //求自然数幂和的前k+2项;
f[i] = (f[i-1]+pow(i*1LL, k))%mod;
}
if(n<=k+2) {
cout<<f[n]<<endl;
return 0;
}
fac[0] = 1; //求前k+2项阶乘;
for(int i = 1; i<=k+2; i++) {
fac[i] = (fac[i-1]*i)%mod;
}
ll cur = 1, ans = 0; //预处理分式的分子;
for(int i = 1; i<=k+2; i++) {
cur = (cur*(n-i))%mod;
}
for(int i = 1; i<=k+2; i++) {
ll inv1 = pow(n-i, mod-2)%mod; //对(n-i)求逆元;
ll inv2 = pow(fac[i-1]%mod*fac[k+2-i]%mod, mod-2)%mod; //对阶乘求逆元;
int sign = (k+2-i)%2?-1:1; //判正负;
ans = (ans + sign*inv1*inv2%mod*f[i]%mod*cur%mod)%mod;
}
ans = (ans+mod)%mod;
cout<<ans<<endl;
return 0;
}