• 求自然数幂和


    求自然数幂和,就是一条公式,然后用代码实现;

          公式描述如下:

     

        

     

         可以看出只要我们预处理出每一项,就可以在线性时间内求得自然数的幂和。前面的倒数可以用递推法求逆元

         预处理,组合数也可以预处理,也可以先预处理,现在关键是如何预处理伯努利数。

     

         伯努利数满足条件,且有

     

        

     

         那么继续得到

     

        

     

         这就是伯努利数的递推式,逆元部分同样可以预处理。

    代码:

    typedef long long ll;
    typedef unsigned long long ull;
    const ll N=2005;
    const ll mod=1e9+7;
    
    ll inv[N],B[N];
    ll C[N][N];
    ll tmp[N];
    ll n,k;
    
    void init()
    {
        //预处理组合数
        for(int i=0;i<N;i++)
        {
            C[i][0]=1;
            for(int j=1;j<=i;j++)
                C[i][j]=(C[i-1][j]%mod+C[i-1][j-1]%mod)%mod;
        }
        //预处理逆元
        inv[1]=1;
        for(int i=2;i<N;i++)
            inv[i]=(mod-mod/i)*inv[mod%i]%mod;
            ;
        // 预处理伯努利数
        B[0]=1;
        for(int i=1;i<N;i++)
        {
            ll ans=0;
            if(i==N-1)break;
            for(int j=0;j<i;j++)
            {
                ans+=C[i+1][j]*B[j];
                ans%=mod;
            }
            ans*=-inv[i+1];
            ans=(ans%mod+mod)%mod;
            B[i]=ans;
        }
    }
    ll work(ll k)
    {
        ll ans=inv[k+1];
        ll sum=0;
        for(int i=1;i<=k+1;i++)
        {
            sum+=C[k+1][i]*tmp[i]%mod*B[k+1-i]%mod;
            sum%=mod;
        }
        ans*=sum;
        ans%=mod;
        return ans;
    }
    ll sum(ll n,ll k)
    {
        if(n<0)return 0;
        n%=mod;
        tmp[0]=1;
        for(int i=1;i<N;i++)
            tmp[i]=tmp[i-1]*(n+1)%mod;
        return work(k);
    }

    参考博客:https://blog.csdn.net/acdreamers/article/details/38929067

  • 相关阅读:
    Nginx源码编译安装
    nginx版本对比
    k8s中subpath挂载单个文件报错处理
    C++ array 数组函数
    洛谷 P2141
    c++ set容器
    字符串中输出每一个元素的方法
    string中的pop_back()函数
    如何去掉前导0 在字符串中 算法
    pat 乙级1074
  • 原文地址:https://www.cnblogs.com/zhgyki/p/9446547.html
Copyright © 2020-2023  润新知