o_o 当前时间是:

4:41:00 PM

 

51NOD 1258 自然数幂和

题目链接

description

T 次询问,每次给定 n,k,求 i=1nik 模 1e9+7.

n1018,k5×104

solution

可以拉插用什么多项式

考虑将 n 带入 f(x)=i=1xik。可以证明,f(x) 是一个 k+1 次多项式。

一种感性的理解方式是 ik 积分后是个 k+1 次函数

于是我们可以通过拉格朗日插值法构造出这个多项式在 n 处的取值。

我们容易线性筛求出 f(x)1,2,,k,k+1,k+2 处的点值,根据 n+1 个点确定一个 n 次多项式,我们可以通过这些点值构造出这个多项式。

t=k+2sp=i=1pik,对于 1pt,pZ,构造函数 gp(x)=spi=1,ipt(xi)(pi)。不难验证,x[1,t]Z,xpgp(x)=0gp(p)=sp

于是可以得出 f(x)=p=1tgp(x)=p=1tspi=1,ipt(xi)(pi)

于是 f(n)=p=1tspi=1,ipt(ni)(pi)

线性筛出 sp,预处理阶乘以及 ni 的前缀后缀积,即可做到严格线性。

时间复杂度 O(Tk)

code

#include<bits/stdc++.h>
using namespace std;
const int N=(1<<18)+10,mod=1e9+7;
int f[N],n,k,m;
bitset<N> st;
int ksm(int a,int b){
int ret=1;
while(b){
if(b&1) ret=ret*1ll*a%mod;
a=a*1ll*a%mod;
b>>=1;
}
return ret;
}
vector<int> primes;
int pre[N],sfx[N],jc[N];
void solve(){
long long nn;
cin>>nn;
nn%=mod;
cin>>k;
n=nn;
primes.clear();
st.reset();
m=k+2;
f[1]=1;
for(int i=2; i<=m; i++){
if(!st[i]){
f[i]=ksm(i,k);
primes.emplace_back(i);
}
for(auto j:primes){
if(i*j>m) break;
st[i*j]=1;
f[i*j]=f[i]*1ll*f[j]%mod;
if(i%j==0){
break;
}
}
}
for(int i=2; i<=m; i++){
f[i]=(f[i-1]+f[i])%mod;
}
jc[0]=pre[0]=sfx[m+1]=1;
for(int i=1; i<=m; i++){
jc[i]=jc[i-1]*1ll*i%mod;
pre[i]=pre[i-1]*1ll*(n-i)%mod;
}
for(int i=m; i; i--){
sfx[i]=sfx[i+1]*1ll*(n-i)%mod;
jc[i]=i==m?ksm(jc[i],mod-2):jc[i+1]*1ll*(i+1)%mod;
}
int ans=0;
for(int i=1; i<=m; i++){
int t=sfx[i+1]*1ll*pre[i-1]%mod*jc[i-1]%mod*jc[m-i]%mod;
if((m-i)&1) t=mod-t;
ans=(ans+t*1ll*f[i]%mod)%mod;
}
cout<<ans<<'\n';
}
int main(){
int T;
cin>>T;
while(T--) solve();
return 0;
}
posted @   zzafanti  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
浏览器标题切换
浏览器标题切换end
点击右上角即可分享
微信分享提示