【CodeForces 622F】The Sum of the k-th Powers
链接:
题目大意:
求出:
\[\sum_{i=1}^{n}i^k\bmod(10^9+7)
\]
正文:
这是一个 \(k+1\) 次的多项式,那么我们如果知道 \(k+2\) 个点就可以确定这个多项式。设 \((x_i,y_i)\) 表示第 \(i\) 个点的坐标,在本题,\(x_i=i,y_i=F(i)\)。将这个代入拉格朗日插值公式:
\[F(n)=\sum_{i=1}^{k+2}F(i)\prod_{j\neq i}\frac{n-j}{i-j}\quad(n>k+2)
\]
然后要把这个式子化一下:
\[\begin{aligned}F(n)&=\sum_{i=1}^{k+2}F(i)\frac{\left(\frac{\prod\limits_{j=n-k-1}^{n-1}j}{n-i}\right)}{(i-1)!(k+2-i)!}\cdot(-1)^{k+2-i}\\&=\left(\prod\limits_{j=n-k-1}^{n-1}j\right)\sum_{i=1}^{k+2}F(i)\frac{(-1)^{k+2-i}}{(i-1)!(k+2-i)!(n-i)}\end{aligned}
\]
所以在 \(n>k+2\) 时就 \(\mathcal{O}(k\log p)\) 解决了,其中 \(p\) 是模数。当 \(n\leq k+2\) 时,由于 \(k\leq 10^6\),就直接 \(\mathcal{O}(n)\) 解决。
代码:
ll fac[M], res, sum, ans, mod = 1e9 + 7;
int n, k;
ll qpow(ll a, int b)
{
ll ans = 1;
for (; b; b >>= 1, a = a * a % mod)
if (b & 1) ans = ans * a % mod;
return ans;
}
int main()
{
scanf ("%d%d", &n, &k);
if (n <= M)
{
for (int i = 1; i <= n; i++)
ans = (ans + qpow(i, k)) % mod;
printf ("%lld\n", ans);
return 0;
}
fac[0] = res = 1;
for (int i = 1; i <= k + 2; i++)
{
res = res * (n - i) % mod;
fac[i] = fac[i - 1] * i % mod;
}
for (int i = 1; i <= k + 2; i++)
{
sum = (sum + qpow(i, k)) % mod;
ll val = sum * qpow(fac[i - 1] * fac[k + 2 - i] % mod * (n - i) % mod, mod - 2);
ans = (ans + val * (((k + 2 - i) & 1)? -1: 1)) % mod;
}
printf ("%lld\n", (ans * res) % mod);
return 0;
}