定義伯努利數列\(b_n\)滿足:
\[b_0=1,\sum_^nb_i=0(n>0) \]
可以發現定義式裡面包含了\(b_n\)這一項,於是把\(b_n\)提出來:
\[-b_n=\sum_^b_i \\-(n+1)b_n=\sum_^b_i \\b_n=-\frac\sum_^b_i \]
直接用定義式求是\(o(n^2)\)的複雜度
把定義式的迴圈上界減一,得:
\[\sum_^b_i=0 \]
注意到組合數上標變成了\(n\),再加個\(b_n\):
\[\sum_^b_i+b_n=b_n \\\sum_^b_i+b_n=b_n \\\sum_^b_i=b_n \]
組合數很煩,把它拆開來:
\[\sum_^\fracb_i=b_n \\\sum_^n\frac\frac=\frac \]
兩邊都寫成生成函式的形式:
\[\sum_(\sum_^n\frac\frac)x^n =\sum_(\frac)x^n \]
設伯努利數的指數型生成函式為\(b(x)=\sum_\fracx^n\),那麼左邊顯然就是\(b(x)e^x\),右邊就是\(b(x)\)。
但是細想卻不對勁,如果\(b(x)e^x=b(x)\),那麼\(e^x=1\),顯然不成立。注意到一開始把迴圈上標減了1,而根據定義,伯努利數定義式的\(n\)必須大於\(0\),所以上面的式子只有當\(n-1>0\)時成立。
於是考慮列出\(b(x)e^x\)的第\(0,1\)項:
\[[x^n]b(x)e^x=\sum_^n\frac\frac \\ [x^0]b(x)e^x=b_0 \\ [x^1]b(x)e^x=b_0+b_1 \]
而\(b(x)\)的第一項只有\(b_1x\),少了個\(b_0x\),加上去即可:
\[b(x)e^x=b(x)+b_0x=b(x)+x \]
可以解出\(b(x)=\frac\)。
注意到分母的第\(0\)次項為\(0\),所以把分子除下去之後,第\(0\)次項不為\(0\),可以用多項式求逆\(o(nlogn)\)做。
說了這麼多,伯努利數有什麼用?
答:可以求解自然數冪和。
定義自然數冪和\(s(m,k)=\sum_^mi^k\),直接求單個是\(o(nlogn)\)的(快速冪是\(o(logn)\))。使用伯努利數可以對於固定的\(m\)做到\(o(nlogn)\)求出前\(n\)個。
下面說下求法:
對於固定的\(m\),還是設\(s(m,k)\)的指數型生成函式為
\[s_m(x)=\sum_\frac^mi^k}x^k \]
交換求和符號得到:
\[s_m(x)=\sum_^m\sum_\fracx^k \\=\sum_^me^=\frac-e^x} \]
注意到分母和\(b(x)\)一樣,把\(b(x)\)帶進去:
\[s_m(x)=b(x)\frac-e^x}=b(x)\frac(e^-1) \]
把\(e^\)展開得到:
\[s_m(x)=b(x)\frac(\sum_\frac-1) \\=b(x)\frac\sum_\frac \\=b(x)e^x\sum_\frac} \\=b(x)e^x\sum_\fracx^i} \]
前面這個\(b(x)e^x\)不好處理,但注意到\(b(x)e^x=b(x)+x\),於是引入新的\(b'(x)=b(x)+x\),把\(b'(x)\)展開:
\[s_m(x)=(\sum_\fracx^i)(\sum_\frac}x^i) \\=\sum_(\sum_^n\frac\frac})x^n \\=\sum_(\sum_^nb'_im^)\frac \\=\sum_(\frac\sum_^nb'_im^)\frac \]
注意到\(s_m(x)=\sum_s(m,k)\frac\),所以:
\[s(m,k)=\frac\sum_^kb'_im^ \]
這個就可以稱為自然數冪和的通項公式。
注意到通項公式可以寫成卷積的形式:
\[s(m,k)=\frac\sum_^kb'_im^ \\=k!\sum_^k\frac\frac} \]
因為\(b'(x)=b(x)+x\),可以\(o(nlogn)\)求出每一項\(b'_n\),所以可以\(o(nlogn)\)求出\(m\)固定時\(k\in[1,n]\)的\(s(m,k)\)值
luogup3711倉鼠的數學題
已知\(a_0...a_n\),設\(s_k(x)=\sum_^xi^k\),求出\(\sum_^ns_k(x)a_k\),並輸出其每一項的係數,可以證明答案是個\(n+1\)次多項式。\(n\leq 250000\),\(0^0=1\),答案對\(998244353\)取模。
可以發現這裡的\(s_k(x)\)相比上面所說的多了個下標\(0\)。但是發現當\(k>0\)時,\(0^k=0\),所以\(s_k(x)=\sum_^xi^k(k>0)\);而當\(k=0\)時,\(0^k=1\),所以\(s_k(x)=\sum_^xi^k+1(k=0)\)。
所以可以重新定義\(s_k(x)\)為\(\sum_^xi^k\),這樣答案的式子就是:
\[a_0+\sum_^ns_k(x)a_k \]
只需要關注前面的求和式,用伯努利數將其展開得到:
\[\sum_^n(k!\sum_^k\frac\frac})a_k \\=\sum_^na_kk!\sum_^k\frac\frac} \\=\sum_^na_kk!\sum_^k\frac}\frac} \\=\sum_^na_kk!\sum_^\frac}\frac \\=\sum_^\frac\sum_^na_kk!\frac} \]
那麼設\(f_i=a_ii!\),\(g_i=\frac\),引入\(g'_i=g_\),那麼上面的式子可以接著寫成:
\[\sum_^\frac\sum_^nf_kg'_ \]
注意到\(g_i=\frac=\frac=[x^i]b'(x)=[x^i](\frac+x)\),可以\(o(nlogn)\)求,答案的卷積也是\(o(nlogn)\),卷積的第\(n+i-1\)次項除以\(i!\)就是答案的第\(i\)項。
注意到上面式子沒有第\(0\)次項,所以答案第\(0\)次項就是\(a_0\)。
#include#define rg register
#define il inline
#define cn const
#define gc getchar()
#define fp(i,a,b) for(rg int i=(a),ed=(b);i<=ed;++i)
#define fb(i,a,b) for(rg int i=(a),ed=(b);i>=ed;--i)
#define add(a,b) (((a)+(b))%mod)
#define inc(a,b) (((a)-(b)+mod)%mod)
#define mul(a,b) (1ll*(a)*(b)%mod)
#define div(a,b) (1ll*(a)*fpow((b,mod-2))%mod)
using namespace std;
typedef cn int cint;
il int rd()
return ans;
}namespace poly
il void ntt(int *a,cint &f)
il void mult(int *a,int *b,int *c,cint &l1,cint &l2,cint &l3)
}int main()
伯努利數學習筆記
伯努利數 b i 的生成函式定義如下 b z frac sum b i times frac 一次多項式求逆即可快速計算 b i 那麼它有啥用呢 可以用來計算自然數冪和 我們記 s p n sum i p 那麼 begin a z,n sum s p n times frac sum sum fra...
伯努利數學習筆記
定義伯努利數列 b n 滿足 b 0 1,sum nb i 0 n 0 可以發現定義式裡面包含了 b n 這一項,於是把 b n 提出來 b n sum b i n 1 b n sum b i b n frac sum b i 直接用定義式求是 o n 2 的複雜度 把定義式的迴圈上界減一,得 su...
學習筆記 伯努利數
b n n 0 frac 1 sum binom i b i 同時有 hat x sum b i frac frac x 所以可以使用多項式求逆求出伯努利數。設自然數冪和函式 s k n sum i k 那麼有 s k n frac 1 sum k binomi b i n 設 hat n x su...