【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;
}
posted @ 2021-02-16 16:20  stoorz  阅读(47)  评论(0编辑  收藏  举报