zoukankan      html  css  js  c++  java
  • 自然数幂和&伯努利数(Bernoulli)

    二项式定理求自然数幂和

    由二项式定理展开得

    [(n+1)^{k+1}-n^{k+1}=inom {k+1}1n^k+inom {k+1}2n^{k-1}+cdots+inom {k+1}kn+1 ]

    那么,对于所有的(n=1,2,3,cdots)累加得到

    [(n+1)^{k+1}-1=inom{k+1}1sum_{i=1}^ni^k+inom{k+1}2sum_{i=1}^ni^{k-1}+cdots+inom {k+1}ksum_{i=1}^ni+n ]

    进一步得到

    [sum_{i=1}^ni^k=frac1{k+1}[(n+1)^{k+1}-(inom{k+1}2sum_{i=1}^ni^{k-1}+cdots+inom {k+1}ksum_{i=1}^ni+n+1)] ]

    (S(n,k)=sum_{i=1}^ni^k),可以得到

    [S(n,k)=frac1{k+1}[(n+1)^{k+1}-(inom{k+1}2S(n,k-1)+cdots+inom {k+1}kS(n,1)+n+1)] ]

    (k==1),有(S(n,1)=frac{ncdot(n+1)}{2})

    加入记忆化即可。

    伯努利数

    [sum_{i=1}^ni^k=frac{1}{k+1}sum_{i=1}^{k+1}inom {k+1}iB_{k+1-i}(n+1)^i ]

    伯努利数满足(B_0=1),且有

    [sum_{k=0}^ninom{n+1}kB_k=0 ]

    那么有

    [B_n=-frac1{n+1}(inom{n+1}0B_0+inom{n+1}1B_1+dots+inom{n+1}{n-1}B_{n-1}) ]

    这样就可以(O(n^2))预处理出伯努利数。

    还可以对(B_i)构建指数型生成函数

    [B(x)=sum_{i=0}^infty frac{B_i}{i!}x^i ]

    经过我也不懂得化简得到

    [egin{split} B(x)=frac{x}{e^x-1}\ B[x]=ifac[x+1] end{split} ]

    可以利用多项式求逆在(O(nlog n))计算伯努利数。

    例题 51nod 1228 序列求和

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<cstdio>
    #include<iomanip>
    #include<cstdlib>
    #define MAXN 0x7fffffff
    typedef long long LL;
    const int N=10005,K=2005,mod=1e9+7;
    using namespace std;
    inline LL Getint(){register LL x=0,f=1;register char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}return x*f;}
    int inv[N],fac[N],ifac[N],B[N];
    int C(int n,int m){
    	if(n<m)return 0;
    	return (LL)fac[n]*ifac[m]%mod*ifac[n-m]%mod;
    }
    int S(LL n,int k){
    	int ret=0;
    	LL ori=(n+1)%mod,fac=ori;
    	for(int i=1;i<=k+1;i++,fac=(LL)fac*ori%mod)
    		ret=(ret+(LL)C(k+1,i)*B[k+1-i]%mod*fac)%mod;
    	return (LL)(ret+mod)%mod*inv[k+1]%mod;
    }
    int main(){
    	inv[1]=fac[0]=ifac[0]=1;
    	for(int i=2;i<=K;i++)inv[i]=(LL)inv[mod%i]*(mod-mod/i)%mod;
    	for(int i=1;i<=K;i++)fac[i]=(LL)fac[i-1]*i%mod;
    	for(int i=1;i<=K;i++)ifac[i]=(LL)ifac[i-1]*inv[i]%mod;
    	B[0]=1;
    	for(int i=1;i<=K;i++){
    		for(int j=0;j<i;j++)
    			B[i]=(B[i]-(LL)B[j]*C(i+1,j))%mod;
    		B[i]=(LL)B[i]*inv[i+1]%mod;
    	}
    	int T=Getint();
    	while(T--){
    		LL n=Getint(),k=Getint();
    		cout<<S(n,k)<<'
    ';
    	}
    	return 0;
    }
    
  • 相关阅读:
    【回溯】数字排列问题
    Price List
    NanoApe Loves Sequence-待解决
    【回溯】n皇后问题
    安卓 学习之旅 入门
    mysql链接 显示 error: 'Access denied for user 'root'@'localhost' (using password: NO)'
    javaweb 实战_1
    java 插件安装
    leetcode 最长有效括号
    hdu 1074 Doing Homework
  • 原文地址:https://www.cnblogs.com/Emiya-wjk/p/10216170.html
Copyright © 2011-2022 走看看