The Sum of the k-th Powers

题目:
https://codeforces.com/problemset/problem/622/F

给定 n n n k k k,求
f ( n ) = ∑ i = 1 n i k f(n)=\sum_{i=1}^{n}i^k f(n)=i=1nik
1 ≤ n ≤ 1 0 9 , 0 ≤ k ≤ 1 0 6 1\le n\le10^9,0\le k\le10^6 1n109,0k106

思路:
拉格朗日插值,把 f ( 1 ) , f ( 2 ) . . . f ( k + 2 ) f(1),f(2)...f(k+2) f(1),f(2)...f(k+2)带进去,时间复杂度能降到 O ( k ) O(k) O(k)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+9;
const ll mod=1e9+7;
namespace polysum
{
    
    
    const int D=1e6+9;
    ll p[D],p1[D],p2[D];
    ll qpow(ll a,ll b){
    
    ll res=1;a%=mod;while(b){
    
    if(b&1)res=res*a%mod;a=a*a%mod;b>>=1;}return res;}
    void init(int n)//x=1~n
    {
    
    
        ll res=1;
        for(int i=1; i<=n; i++)res=res*(ll)i%mod;
        res=qpow(res,mod-2);
        p[n]=res;
        for(int i=n-1;i>=0;i--)
            p[i]=p[i+1]*(i+1)%mod;
    }
    ll polysum(int n,ll *a,ll m)//a[1]...a[n]   a[m]
    {
    
    
        if(1<=m&&m<=(ll)n)
            return a[(int)m];
        ll res=0;
        p1[1]=p2[n]=1;
        for(int i=2; i<=n; i++)p1[i]=p1[i-1]*(ll)(m-i+1)%mod;
        for(int i=n-1; i>=1; i--)p2[i]=p2[i+1]*(ll)(m-i-1)%mod;
        for(int i=1; i<=n; i++)
        {
    
    
            ll tmp=p[i-1]*p[n-i]%mod;
            if((n-i)&1)tmp=tmp*(mod-1)%mod;
            res=(res+a[i]*p1[i]%mod*p2[i]%mod*tmp%mod)%mod;
        }
        return res;
    }
}
ll n,a[N];
int k;
int main()
{
    
    
    cin>>n>>k;
    polysum::init(k+2);
    a[0]=0;
    for(int i=1; i<=k+2; i++)
        a[i]=(a[i-1]+polysum::qpow(i,k))%mod;
    cout<<polysum::polysum(k+2,a,n);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43520313/article/details/108771496