zoukankan      html  css  js  c++  java
  • CF622F The Sum of the k-th Powers

    CF622F The Sum of the k-th Powers

    题意:求 (sumlimits_{i=1}^ni^k\%1000000007) ,(nle 10^9,kle 10^6)

    (k) 次幂和是一个 (k+1) 次多项式 ,带 (k+2) 个点进去插值就好了。证明不会,感觉很正确就是了。

    [f(n)=sum_{i=1}^{k+2}y_iprod_{j ot=i}dfrac{n-x_j}{x_i-x_j} ]

    其中每个点是 ((n,sumlimits_{i=1}^{n}i^k))

    线性筛 (i^k) 求前缀和为 (s_i),阶乘,阶乘的逆元,预处理分母的前缀积后缀积(就是阶乘 (fac) 及其逆元 (ifc))以及分子的前缀积 (pre) 后缀积 (suf) 可以做到 (O(k))

    [f(n)=sum_{i=1}^{k+2}s_i prod_{j ot=i}dfrac{pre[i-1]*suf[i+1]}{(i-1)!(k+2-i)!(-1)^{k+2-i}} ]

    注意分母 ((k+2-i)!) 可能有个 (-1) 的系数,判断一下

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef double db;
    #define pb(x) push_back(x)
    #define mkp(x,y) make_pair(x,y)
    //#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    //char buf[1<<21],*p1=buf,*p2=buf;
    inline int read() {
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch))x=x*10+(ch^48),ch=getchar();
    	return x*f;
    }
    const int N=1000005;
    const int mod=1e9+7;
    int n,k,ans;
    int pri[N/9],cnt,s[N],inv[N],fac[N],ifc[N];
    bool vis[N];
    int pre[N],suf[N];
    int qpow(int n,int k){
    	int res=1;
    	for(;k;k>>=1,n=1ll*n*n%mod)
    		if(k&1)res=1ll*n*res%mod;
    	return res;
    }
    void fmod(int&x){
    	x+=x>>31&mod,x-=mod,x+=x>>31&mod;
    }
    void Sieve(const int&N){
    	s[1]=1;
    	for(int i=2;i<=N;++i){
    		if(!vis[i])pri[++cnt]=i,s[i]=qpow(i,k);
    		for(int j=1;j<=cnt&&i*pri[j]<=N;++j){
    			vis[i*pri[j]]=1;s[i*pri[j]]=1ll*s[i]*s[pri[j]]%mod;
    			if(i%pri[j]==0)break;
    		}
    	}
    	for(int i=1;i<=N;++i)fmod(s[i]+=s[i-1]);
    	inv[1]=1;for(int i=2;i<=N;++i)inv[i]=1ll*inv[mod%i]*(mod-i)%mod;
    	fac[0]=1;for(int i=1;i<=N;++i)fac[i]=1ll*i*fac[i-1]%mod;
    	ifc[N]=qpow(fac[N],mod-2);for(int i=N-1;i>=0;--i)ifc[i]=1ll*ifc[i+1]*(i+1)%mod;
    	pre[0]=1;for(int i=1;i<=N;++i)pre[i]=1ll*pre[i-1]*(n-i)%mod;
    	suf[N+1]=1;for(int i=N;i>0;--i)suf[i]=1ll*suf[i+1]*(n-i)%mod;
    }
    void lagrange(){
    	for(int i=1;i<=k+2;++i){
    		int A=1ll*pre[i-1]*suf[i+1]%mod;
    		int B=1ll*ifc[i-1]*((k+2-i)&1?-1:1)*ifc[k+2-i]%mod;
    		ans=(ans+1ll*s[i]*A%mod*B%mod)%mod;
    	}
    }
    signed main(){
    	cin>>n>>k,Sieve(k+2);
    	if(n<=k+2)return cout<<s[n]<<'
    ',0;
    	lagrange(),fmod(ans),cout<<ans<<'
    ';
    	return 0;
    }
    
    路漫漫其修远兮,吾将上下而求索
  • 相关阅读:
    Go map 切片
    Go map 增删改查和遍历
    Go map 基本使用
    Go 二维数组
    Go 切片
    Go 数组
    Go 错误处理 defer recover panic
    Go time模块
    5分钟入门MP4文件格式
    写盘工具
  • 原文地址:https://www.cnblogs.com/zzctommy/p/13790125.html
Copyright © 2011-2022 走看看