• 从伯努利数到自然数幂和


    伯努利数

    伯努利数是定义在实数上的一个数列,其在( m OI)中的用处大多都是处理自然数幂和。

    定义

    我们定义伯努利数(B_i)满足:

    [B_0=1,sum_{i=0}^{n}inom{n+1}{i}B_i=0 (n>0) ]

    那么易得:

    [B_0=1,B_1=-frac{1}{2},B_2=frac{1}{6},B_3=0,B_4=-frac{1}{30},B_5=0,... ]

    注意到奇数位除了(B_1)都为(0)

    求解伯努利数

    首先很显然的我们把定义式移个项就可以得到(O(n^2))的做法:

    [B_n=-frac{1}{n+1}sum_{i=0}^{n-1}inom{n+1}{i}B_i ]


    其实我们通过一些奥妙重重的方法可以做到(O(nlog n))

    我们把定义式抄下来:

    [sum_{i=0}^{n}inom{n+1}{i}B_i=0\ sum_{i=0}^{n-1}inom{n}{i}B_i=0 ]

    注意第二个式子要保证(n>1)

    [sum_{i=0}^{n-1}inom{n}{i}B_i+B_n=B_n\ sum_{i=0}^{n}inom{n}{i}B_n=B_n\ sum_{i=0}^{n}frac{B_i}{i!(n-i)!}=frac{B_n}{n!} ]

    注意到这是个卷积的形式,我们写出(B_i)的指数型生成函数:

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

    那么显然等式左边就是(B(x))卷上(e^x),但是注意到上面那个等式只在(n>1)时成立,我们手玩一下(n=0,1)时卷积的样子:

    [egin{align} B(x)e^x&=B_0+(B_0+B_1)x+cdots\ B(x)&=B_0+B_1x+cdots end{align} ]

    显然(B(x))少了个(B_0x=x),我们加上就好了,可得:

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

    那么我们直接多项式求逆就可以做到(O(nlog n))

    利用伯努利数求解幂和

    定义:

    [S_p(n)=sum_{i=1}^{n}i^p ]

    然后我们搞出这个函数的指数型生成函数:

    [egin{align} G_n(x)&=sum_{i=0}^{infty}frac{S_i(n)}{i!}x^i\ &=sum_{i=0}^{infty}frac{x^i}{i!}sum_{j=1}^{n}j^i\ &=sum_{j=1}^{n}sum_{i=0}^{infty}frac{(jx)^i}{i!}\ &=sum_{j=1}^{n}e^{jx}=frac{e^{(n+1)x}-e^{x}}{e^x-1}\ end{align} ]

    后面一个是根据(e^{F(x)})的定义来的,即:

    [e^{F(x)}=sum_{i=0}^{infty}frac{F^i(x)}{i!} ]

    注意到分母和(B(x))长的一样,我们把(B(x))套进去:

    [egin{align} G_n(x)&=B(x)frac{e^{(n+1)x}-e^x}{x}\ &=B(x)e^xcdot frac{1}{x}cdot left(-1+sum_{i=0}^{infty}frac{n^ix^i}{i!} ight)\ end{align} ]

    注意到前面有一个等式是这样的:(B(x)e^x=B(x)+x)

    由于后面这个(x)不好处理,我们定义一个新的伯努利数(B'(x)=B(x)+x),注意到这个新的数列只有第一项和伯努利数不同,(B'(1)=-B(1))

    因为只有一项不同,下面的式子为了美观把B'写成了B

    [egin{align} G_n(x)&=left(sum_{i=0}^{infty}frac{B_i}{i!}x^i ight)cdot left(sum_{i=0}^{infty}frac{n^{i+1}}{(i+1)!}x^i ight)\ &=sum_{i=0}^{infty}x^isum_{j=0}^{i}frac{n^{j+1}}{(j+1)!}cdot frac{B_{i-j}}{(i-j)!}\ &=sum_{i=0}^{infty}frac{x^i}{i!}cdot frac{1}{i+1}sum_{j=0}^iinom{i+1}{j+1}B_{i-j}n^{j+1} end{align} ]

    对比系数可知:

    [egin{align} S_i(n)&=frac{1}{i+1}sum_{j=0}^iinom{i+1}{j+1}B_{i-j}n^{j+1}\ &=frac{1}{i+1}sum_{j=0}^{i}inom{i+1}{i-j+1}B_jn^{i-j+1}\ &=frac{1}{i+1}sum_{j=0}^{i}inom{i+1}{j}B_jn^{i-j+1}\ end{align} ]

    那么写的好看一点,结论就是:

    [sum_{i=1}^{n}i^k=frac{1}{k+1}sum_{j=0}^{k}inom{k+1}{j}B_jn^{k-j+1} ]

    代码:

    void get_Bernoulli() {
        b[0]=1;
        for(int i=1;i<N;i++) {
            for(int j=0;j<i;j++) b[i]=add(b[i],mul(b[j],c(i+1,j)));
            b[i]=del(0,mul(b[i],inv[i+1]));
        }b[1]++;  //注意下这里
    }
    void get_coefficient() {
     	s[0]=0;
        for(int i=0;i<=n;i++) s[y+1-i]=mul(inv[y+1],mul(b[i],c(y+1,i)));
    }
    

    多项式求逆不想写了,以后遇到题再写吧

  • 相关阅读:
    Oracle 分析函数
    Oracle 增加修改删除字段
    Oracle 重置序列
    End2EndIT
    Hyperledger Fabric SDK use case 1
    云计算中8项核心技术
    Cloud
    JVM Guide
    微信公众平台PHP开发
    在Linux系统环境下修改MySQL的root密码
  • 原文地址:https://www.cnblogs.com/hbyer/p/10821363.html
Copyright © 2020-2023  润新知