版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
题目大意是求:对 取模。
当 k = 1时,
当 k = 2时,
当 k = 3时,
我们可以发现所求答案为k+1次多项式。我们只需要计算出k+2个点,然后应用拉格朗日插值法就可以得到此多项式。
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 8;
const ll mod = 1e9 + 7;
ll n, k, f[maxn], fact[maxn];
ll power(ll a, ll b)
{
ll ans = 1;
a %= mod;
while(b) {
if(b & 1) ans = (ans * a) % mod;
a = (a * a) % mod;
b >>= 1;
}
return ans;
}
int main()
{
while(scanf("%lld %lld", &n, &k) == 2) {
f[0] = 0;
for(int i = 1; i <= k+2; i++) f[i] = (f[i-1] + power(i, k)) % mod;
if(n <= k+2) {
printf("%lld\n", f[n]);
continue;
}
fact[0] = 1;
for(int i = 1; i <= k+2; i++) fact[i] = (fact[i-1] * i) % mod;
ll cur = 1;
for(int i = 1; i <= k+2; i++) cur = (cur * (n-i)) % mod;
ll ans = 0;
ll sign = 1;
for(int i = 1; i <= k+2; i++) {
ll inv1 = power(n-i, mod-2) % mod;
ll inv2 = power(fact[i-1] % mod * fact[k+2-i] % mod, mod-2);
if((k+2-i) & 1) sign = -1;
else sign = 1;
ans = (ans + sign * inv1 * inv2 % mod * cur % mod * f[i] % mod) % mod;
}
ans = (ans + mod) % mod;
printf("%lld\n", ans);
}
return 0;
}