【CF622F】The Sum of the k-th Powers
题目
题目链接:https://codeforces.com/problemset/problem/622/F
求
\[\sum^{n}_{i=1}i^k
\]
\(n\leq 10^9,k\leq 10^6\)。
思路
可以证明这个东西是关于 \(n\) 的 \(k+1\) 次多项式。不会证太菜了当结论记。
所以可以直接将 \(i=1\sim k+2\) 带进去,直接上拉格朗日插值可以做到 \(O(k^2)\)。
观察一下式子
\[f(n)=\sum^{k+2}_{i=1}f(i)\prod_{j\neq i}\frac{n-j}{i-j}
\]
其实等价于
\[f(n)=(n-1)^{\underline{k+1}}\sum^{k+2}_{i=1}f(i)\frac{(-1)^{k+2-i}}{(i-1)!(k+2-i)!(n-i)}
\]
然后就可以 \(O(k\log p)\) 计算了。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1000010,MOD=1e9+7;
int n,k;
ll ans,res,sum,fac[N];
ll fpow(ll x,ll k)
{
ll ans=1;
for (;k;k>>=1,x=x*x%MOD)
if (k&1) ans=ans*x%MOD;
return ans;
}
int main()
{
scanf("%d%d",&n,&k);
if (n<=N)
{
for (int i=1;i<=n;i++)
ans=(ans+fpow(i,k))%MOD;
printf("%lld",ans);
return 0;
}
fac[0]=res=1;
for (int i=1;i<=k+2;i++)
{
fac[i]=fac[i-1]*i%MOD;
res=res*(n-i)%MOD;
}
for (int i=1;i<=k+2;i++)
{
sum=(sum+fpow(i,k))%MOD;
ll val=sum*fpow(fac[i-1]*fac[k+2-i]%MOD*(n-i)%MOD,MOD-2);
ans=(ans+(((k+2-i)&1)?-1:1)*val)%MOD;
}
printf("%lld",((ans*res)%MOD+MOD)%MOD);
return 0;
}