伯努利数
伯努利数是定义在实数上的一个数列,其在( 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)));
}
多项式求逆不想写了,以后遇到题再写吧