第一道拉格朗日插值
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 1000006;
const LL mod = 1e9 + 7;
int n, k;
LL po[maxn];//prod_i(1~maxn)
LL ne[maxn];//prod_i (-1~-maxn)
LL c[maxn];//系数 po[i-1]*ne[i-k-2]
LL S, Y[maxn];
LL x, y;
LL ex_gcd(LL num1, LL num2)
{
if (!num2)
{
x = 1;
y = 0;
return num1;
}
LL ans = ex_gcd(num2, num1%num2);
LL tmp = x;
x = y;
y = tmp - (num1 / num2)*x;
return ans;
}
LL inv(LL xx){
ex_gcd(xx, mod);
return (x % mod + mod) % mod;
}
void pre(){
po[0] = ne[0] = 1;
for (int i = 1; i <= k + 2; i++){
int x = mod - i;
po[i] = (po[i - 1] * i) % mod;
ne[i] = (ne[i - 1] * x) % mod;
}
for (int i = 1; i <= k + 2; i++){
c[i] = (inv(po[i - 1]) * inv(ne[k + 2 - i])) % mod;
}
S = 1;
for (int i = n - k - 2; i <= n - 1; i++){
S = (S*i) % mod;
}
}
LL pow(LL a, int k){
LL ret = 1;
while (k){
if (k & 1) ret = (ret * a) % mod;
a = (a * a) % mod;
k >>= 1;
}
return ret;
}
int main(){
cin >> n >> k;
if (!k){
cout << n << endl;
return 0;
}
for (int i = 1; i <= min(k + 2, n); i++){
Y[i] = (Y[i - 1] + pow(i*1LL, k)) % mod;
}
if (n <= k + 2){
printf("%d\n", Y[n]);
return 0;
}
pre();
LL ret = 0;
for (int i = 1; i <= k + 2; i++){
LL mid = (((c[i] * S) % mod) * Y[i])%mod;
ret = (ret + mid * inv(n - i)) % mod;
}
cout << ret << endl;
return 0;
}