zoukankan      html  css  js  c++  java
  • Codeforces 622F The Sum of the k-th Powers ( 自然数幂和、拉格朗日插值法 )

    题目链接

    题意 : 就是让你求个自然数幂和、最高次可达 1e6 、求和上限是 1e9

    分析 : 

    题目给出了最高次 k = 1、2、3 时候的自然数幂和求和公式

    可以发现求和公式的最高次都是 k+1

    那么大胆猜测幂为 k 的自然数幂和肯定可以由一个最高次为 k+1 的多项式表示

    不会证明,事实也的确如此

    此时就变成了一个拉格朗日插值的模板题了

    只要先算出 k+2 个值、然后就能确定最高次为 k+1 的多项式

    套模板求值即可

    当然自然数幂和不止这一种做法、例如伯努利数、斯特林数等

    详细可参考 ==> Click here

    #include<bits/stdc++.h>
    #define LL long long
    #define ULL unsigned long long
    
    #define scs(i) scanf("%s", i)
    #define sci(i) scanf("%d", &i)
    #define scd(i) scanf("%lf", &i)
    #define scIl(i) scanf("%I64d", &i)
    #define scii(i, j) scanf("%d %d", &i, &j)
    #define scdd(i, j) scanf("%lf %lf", &i, &j)
    #define scIll(i, j) scanf("%I64d %I64d", &i, &j)
    #define sciii(i, j, k) scanf("%d %d %d", &i, &j, &k)
    #define scddd(i, j, k) scanf("%lf %lf %lf", &i, &j, &k)
    #define scIlll(i, j, k) scanf("%I64d %I64d %I64d", &i, &j, &k)
    #define sciiii(i, j, k, l) scanf("%d %d %d %d", &i, &j, &k, &l)
    #define scdddd(i, j, k, l) scanf("%lf %lf %lf %lf", &i, &j, &k, &l)
    #define scIllll(i, j, k, l) scanf("%I64d %I64d %I64d %I64d", &i, &j, &k, &l)
    
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    #define lowbit(i) (i & (-i))
    #define mem(i, j) memset(i, j, sizeof(i))
    
    #define fir first
    #define sec second
    #define VI vector<int>
    #define ins(i) insert(i)
    #define pb(i) push_back(i)
    #define pii pair<int, int>
    #define VL vector<long long>
    #define mk(i, j) make_pair(i, j)
    #define all(i) i.begin(), i.end()
    #define pll pair<long long, long long>
    
    #define _TIME 0
    #define _INPUT 0
    #define _OUTPUT 0
    clock_t START, END;
    void __stTIME();
    void __enTIME();
    void __IOPUT();
    using namespace std;
    const int maxn = 1e6 + 10;
    const LL mod = 1e9 + 7;
    
    LL pow_mod(LL a, LL b)
    {
        a %= mod;
        LL ret = 1;
        while(b){
            if(b & 1) ret = (ret * a) % mod;
            a = ( a * a ) % mod;
            b >>= 1;
        }
        return ret;
    }
    
    namespace polysum
    {
        #define rep(i,a,n) for (int i=a;i<n;i++)
        #define per(i,a,n) for (int i=n-1;i>=a;i--)
        const int D=1e6+200;
        LL a[D],f[D],g[D],p[D],p1[D],p2[D],b[D],h[D][2],C[D];
        LL powmod(LL a,LL b){LL res=1;a%=mod;assert(b>=0);for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
        LL calcn(int d,LL *a,LL n) { // a[0].. a[d]  a[n]
            if (n<=d) return a[n];
            p1[0]=p2[0]=1;
            rep(i,0,d+1) {
                LL t=(n-i+mod)%mod;
                p1[i+1]=p1[i]*t%mod;
            }
            rep(i,0,d+1) {
                LL t=(n-d+i+mod)%mod;
                p2[i+1]=p2[i]*t%mod;
            }
            LL ans=0;
            rep(i,0,d+1) {
                LL t=g[i]*g[d-i]%mod*p1[i]%mod*p2[d-i]%mod*a[i]%mod;
                if ((d-i)&1) ans=(ans-t+mod)%mod;
                else ans=(ans+t)%mod;
            }
            return ans;
        }
        void init(int M) {
            f[0]=f[1]=g[0]=g[1]=1;
            rep(i,2,M+5) f[i]=f[i-1]*i%mod;
            g[M+4]=powmod(f[M+4],mod-2);
            per(i,1,M+4) g[i]=g[i+1]*(i+1)%mod;
        }
        LL polysum(LL m,LL *a,LL n) { // a[0].. a[m] sum_{i=0}^{n-1} a[i]
    
            for(int i=0;i<=m;i++) b[i]=a[i];
            b[m+1]=calcn(m,b,m+1);
            rep(i,1,m+2) b[i]=(b[i-1]+b[i])%mod;
            return calcn(m+1,b,n-1);
        }
        LL qpolysum(LL R,LL n,LL *a,LL m) { // a[0].. a[m] sum_{i=0}^{n-1} a[i]*R^i
            if (R==1) return polysum(n,a,m);
            a[m+1]=calcn(m,a,m+1);
            LL r=powmod(R,mod-2),p3=0,p4=0,c,ans;
            h[0][0]=0;h[0][1]=1;
            rep(i,1,m+2) {
                h[i][0]=(h[i-1][0]+a[i-1])*r%mod;
                h[i][1]=h[i-1][1]*r%mod;
            }
            rep(i,0,m+2) {
                LL t=g[i]*g[m+1-i]%mod;
                if (i&1) p3=((p3-h[i][0]*t)%mod+mod)%mod,p4=((p4-h[i][1]*t)%mod+mod)%mod;
                else p3=(p3+h[i][0]*t)%mod,p4=(p4+h[i][1]*t)%mod;
            }
            c=powmod(p4,mod-2)*(mod-p3)%mod;
            rep(i,0,m+2) h[i][0]=(h[i][0]+h[i][1]*c)%mod;
            rep(i,0,m+2) C[i]=h[i][0];
            ans=(calcn(m,C,n)*powmod(R,n)-c)%mod;
            if (ans<0) ans+=mod;
            return ans;
        }
    
    }
    LL arr[maxn];
    int main(void){__stTIME();__IOPUT();
    
        int n, k;
    
        scii(n, k);
    
        if(k == 0) return !printf("%d
    ", n);
    
        polysum::init(k+100);
    
        for(int i=0; i<=k+1; i++)
            arr[i] = pow_mod((LL)i, (LL)k);
    
        LL res = polysum::polysum(k+1, arr, n+1) - arr[0];
        printf("%I64d
    ", res);
    
    
    
    __enTIME();return 0;}
    
    
    void __stTIME()
    {
        #if _TIME
            START = clock();
        #endif
    }
    
    void __enTIME()
    {
        #if _TIME
            END = clock();
            cerr<<"execute time = "<<(double)(END-START)/CLOCKS_PER_SEC<<endl;
        #endif
    }
    
    void __IOPUT()
    {
        #if _INPUT
            freopen("in.txt", "r", stdin);
        #endif
        #if _OUTPUT
            freopen("out.txt", "w", stdout);
        #endif
    }
    View Code
  • 相关阅读:
    How to change hostname on SLE
    How to install starDIct on suse OS?
    python logging usage
    How to reset password for unknow root
    How to use wget ?
    How to only capute sub-matched character by grep
    How to inspect who is caller of func and who is the class of instance
    How to use groovy script on jenkins
    Vim ide for shell development
    linux高性能服务器编程 (二) --IP协议详解
  • 原文地址:https://www.cnblogs.com/qwertiLH/p/9416665.html
Copyright © 2011-2022 走看看