[CF622F] The Sum of the k-th Powers

\(\text{Problem}:\)The Sum of the k-th Powers

\(\text{Solution}:\)

要求的即自然数幂之和 \(S_{k}(n)\)。将 \(i^{k}\) 用第二类斯特林数展开,有:

\[S_{k}(n)=\sum\limits_{j=1}^{k}{k\brace j}j!\sum\limits_{i=0}^{n-j}\binom{i+j}{j} \]

引理 \(1\)

\[\sum\limits_{j=m}^{n}\binom{j}{m}=\binom{n+1}{m+1} \]

证明:在等式左边添加 \(\binom{m}{m+1}\) 即可。

那么原式转化为:

\[S_{k}(n)=\sum\limits_{j=1}^{k}{k\brace j}j!\binom{n+1}{j+1}=\sum\limits_{j=1}^{k}{k\brace j}\frac{(n+1)^{\underline{j+1}}}{j+1} \]

至此,利用 \(\text{MTT}\)(任意模数多项式卷积)算出一行第二类斯特林数即可在 \(O(k\log k)\) 的时间复杂度内求解。

注意到原式是一个关于 \(n\)\(k+1\) 次多项式,故可以进行拉格朗日插值:

\[S_{k}(n)=\sum\limits_{i=1}^{k+2}S_{k}(i)\prod\limits_{j\not=i}\frac{n-j}{i-j} \]

发现 \(\prod\) 内分子和分母值的变化是连续的,有:

\[\begin{aligned} S_{k}(n)&=\sum\limits_{i=1}^{k+2}S_{k}(i)\prod\limits_{j=1}^{i-1}\frac{n-j}{i-j}\prod\limits_{j=i+1}^{k+2}\frac{n-j}{i-j}\\ &=\sum\limits_{i=1}^{k+2}(-1)^{k+2-i}S_{k}(i)\frac{(n-1)^{\underline{i-1}}(n-i-1)^{\underline{k+2-i}}}{(i-1)!(k+2-i)!} \end{aligned} \]

利用线性筛求出前 \(k+2\) 项的 \(S_{k}(i)\),预处理阶乘的逆元和下降幂即可在 \(O(k)\) 的时间复杂度内解决本题。

\(\text{Code}:\)

#include <bits/stdc++.h>
#pragma GCC optimize(3)
//#define int long long
#define ri register
#define mk make_pair
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define is insert
#define es erase
#define vi vector<int>
#define vpi vector<pair<int,int>>
using namespace std; const int N=1000010, Mod=1e9+7; 
inline int read()
{
	int s=0, w=1; ri char ch=getchar();
	while(ch<'0'||ch>'9') { if(ch=='-') w=-1; ch=getchar(); }
	while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+(ch^48), ch=getchar();
	return s*w;
}
int n,K,pri[N/10],cnt,book[N],f[N],g1[N],g2[N];
int fac[N+5],inv[N+5];
inline int ksc(int x,int p) { int res=1; for(;p;p>>=1, x=1ll*x*x%Mod) if(p&1) res=1ll*res*x%Mod; return res; }
inline void Init()
{
	fac[0]=1;
	for(ri int i=1;i<=N;i++) fac[i]=1ll*fac[i-1]*i%Mod;
	inv[N]=ksc(fac[N],Mod-2);
	for(ri int i=N;i;i--) inv[i-1]=1ll*inv[i]*i%Mod;
	f[1]=1;
	for(ri int i=2;i<N;i++)
	{
		if(!book[i]) pri[++cnt]=i, f[i]=ksc(i,K);
		for(ri int j=1;j<=cnt&&i*pri[j]<N;j++)
		{
			book[i*pri[j]]=1;
			f[i*pri[j]]=1ll*f[i]*f[pri[j]]%Mod;
			if(i%pri[j]==0) break;
		}
	}
	for(ri int i=1;i<N;i++) f[i]=(f[i-1]+f[i])%Mod;
}
signed main()
{
	n=read(), K=read();
	Init();
	int ans=0;
	if(n<=K+2) return printf("%d\n",f[n])&0;
	g1[0]=1;
	for(ri int i=1;i<=K+2;i++) g1[i]=1ll*g1[i-1]*(n-i)%Mod;
	g2[K+3]=1;
	for(ri int i=K+2;i;i--) g2[i]=1ll*g2[i+1]*(n-i)%Mod;
	for(ri int i=1;i<=K+2;i++)
	{
		int w=f[i];
		w=1ll*w*inv[i-1]%Mod*inv[K+2-i]%Mod;
		w=1ll*w*g1[i-1]%Mod*g2[i+1]%Mod;
		if((K+2-i)&1) ans=(ans-w+Mod)%Mod;
		else ans=(ans+w)%Mod;
	}
	printf("%d\n",ans);
	return 0;
}
posted @ 2021-05-01 10:53  zkdxl  阅读(41)  评论(0编辑  收藏  举报