Wonderful! O(m²) 實現等冪求和——伯努利數
阿新 • • 發佈:2022-01-29
等冪求和
伯努利數是以雅各布 \(\cdot\) 伯努利的名字命名的,我們記
\[S_m(n) = \sum_{k = 0}^{n - 1} k^m \]伯努利 暴力 算出了前幾項,並進行了觀察:
我們發現,在 \(S_m(n)\)
遞推公式
根據伯努利的發現(值得一提的是,他並沒有給出證明),我們有
\[S_m(n) = \dfrac{1}{m + 1} \sum_{k = 0}^m \dbinom{m + 1}{k} B_k n^{m + 1 - k} \]其中 \(B_n\) 為伯努利數,其由一個遞迴關係定義:
\[\sum_{k = 0}^m \dbinom{m + 1}{k} B_k = [m = 0] \]其實你也可以寫成
\[B_0 = 1 \\ \sum_{k = 0}^m \dbinom{m + 1}{k} B_k = 0, m \ge 1 \]這樣方便你進行計算。
根據手算,不難得出前幾個值:
\(n\) | \(0\) | \(1\) |
\(2\) | \(3\) | \(4\) | \(5\) | \(6\) | \(7\) | \(8\) | \(9\) | \(10\) | \(11\) | \(12\) |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
\(B_n\) | \(1\) | \(-\dfrac{1}{2}\) | \(\dfrac{1}{6}\) | \(0\) | \(-\dfrac{1}{30}\) | \(0\) | \(\dfrac{1}{42}\) | \(0\) | \(-\dfrac{1}{30}\) | \(0\) | \(\dfrac{5}{66}\) | \(0\) | \(-\dfrac{691}{2730}\) |
(其中 \(B_{12}\) 這個奇怪分數的出現真是給那些有關 \(B_n\) 的簡單封閉形式的猜想潑冷水。)
證明:
首先令
\[\hat{S}_m(n) = \dfrac{1}{m + 1} \sum_{k = 0}^m \dbinom{m + 1}{k} B_k n^{m + 1 - k} \]那麼現在我們就是要證明 \(S_m(n) = \hat{S}_m(n)\),考慮使用數學歸納法。
首先
\[\begin{array}{ll} S_0(n) = \sum\limits_{i = 0}^{n - 1} n^0 = n \\ \hat{S}_0(n) = \dfrac{1}{1} \dbinom{1}{0} B_0 n^{1} = n \end{array} \]\[\begin{aligned} S_{m + 1}(n) + n^{m + 1} & = \sum_{k = 0}^n k^{m + 1} \\ & = \sum_{k = 0}^{n - 1} (k + 1)^{m + 1} \\ & = \sum_{k = 0}^{n - 1} \sum_{j = 0}^{m + 1} \dbinom{m + 1}{j} k^j \\ & = \sum_{j = 0}^{m + 1} \dbinom{m + 1}{j} \sum_{k = 0}^{n - 1} k^j \\ & = \sum_{j = 0}^{m + 1} \dbinom{m + 1}{j} S_j(n) \end{aligned} \]當 \(m\ge 1\) 時,假設 \(\forall i \in [0, m)\) 均有 \(S_i(n) = \hat{S}_i(n)\),將 \(S_{m +1}(n)\) 移項:
\[\begin{aligned} n^{m + 1} & = \sum_{j = 0}^{m + 1} \dbinom{m + 1}{j} S_j(n) - S_{m + 1}(n) \\ & = \sum_{j = 0}^m \dbinom{m + 1}{j} S_j(n) \\ & = \sum_{j = 0}^{m - 1} \dbinom{m + 1}{j} S_j(n) + \dbinom{m + 1}{m} S_m(n) \\ & = \sum_{j = 0}^{m - 1} \dbinom{m + 1}{j} \hat{S}_j(n) + (m + 1) S_m(n) \end{aligned} \]設
\[\Delta = S_m(n) - \hat{S}_m(n) \]那麼現在就是要證 \(\Delta = 0\)。
\[\begin{aligned} n^{m + 1} & = \left[\sum_{j = 0}^{m - 1} \dbinom{m + 1}{j} \hat{S}_j(n) + (m + 1) \hat{S}_m(n) \right] + (m + 1) S_m(n) - (m + 1) \hat{S}_m(n) \\ & = \sum_{j = 0}^m \dbinom{m + 1}{j} \hat{S}_j(n) + (m + 1) \Delta \end{aligned} \]根據 \(\hat{S}_m(n)\) 的定義將其展開,有
\[n^{m + 1} = \sum_{j = 0}^m \dbinom{m +1}{j} \dfrac{1}{j + 1} \sum_{k = 0}^j \dbinom{j + 1}{k} B_k n^{j + 1 - k} + (m + 1) \Delta \]將 \(k\) 改為倒序列舉 並 利用 對稱恆等式
\[\dbinom{n}{m} = \dbinom{n}{n - m}, n\in \mathbb{N}, k \in \mathbb{Z} \]\[\begin{aligned} n^{m +1} & = \sum_{j = 0}^m \dbinom{m + 1}{j} \dfrac{1}{j + 1} \sum_{k = 0}^j \dbinom{j + 1}{j - k} B_{j - k} n^{k + 1} + (m + 1) \Delta \\ & = \sum_{j = 0}^m \dbinom{m + 1}{j} \dfrac{1}{j + 1} \sum_{k = 0}^j \dbinom{j + 1}{k + 1} B_{j - k} n^{k + 1} + (m + 1) \Delta \end{aligned} \]利用 吸收恆等式
\[\dbinom{r}{k} = \dfrac{r}{k} \dbinom{r - 1}{k - 1}, k \in \mathbb{Z}, k \ne 0 \]\[\begin{aligned} n^{m + 1} & = \sum_{j = 0}^m \dbinom{m + 1}{j} \dfrac{1}{j + 1} \sum_{k = 0}^j \dfrac{j + 1}{k + 1} \dbinom{j}{k} B_{j - k} n^{k + 1} + (m +1) \Delta \\ & = \sum_{j = 0}^m \dbinom{m + 1}{j} \sum_{k = 0}^j \dfrac{n^{k + 1}}{k + 1} \dbinom{j}{k} B_{j - k} + (m + 1) \Delta \\ & = \sum_{k = 0}^m \dfrac{n^{k + 1}}{k + 1} \sum_{j = k}^m \dbinom{m + 1}{j} \dbinom{j}{k} B_{j - k} + (m + 1) \Delta \end{aligned} \]利用 三項式版恆等式
\[\dbinom{r}{m} \dbinom{m}{k} = \dbinom{r}{k} \dbinom{r - k}{m - k} \]\[\begin{aligned} n^{m + 1} & = \sum_{k = 0}^m \dfrac{n^{k + 1}}{k + 1} \sum_{j = k}^m \dbinom{m + 1}{k} \dbinom{m - k + 1}{j - k} B_{j - k} + (m + 1) \Delta \\ & = \sum_{k = 0}^m \dfrac{n^{k + 1}}{k + 1} \dbinom{m + 1}{k} \sum_{j = k}^m \dbinom{m - k + 1}{j - k} B_{j - k} + (m + 1) \Delta \end{aligned} \]將 \(j - k\) 改為 \(j\)
\[n^{m + 1} = \sum_{k = 0}^m \dfrac{n^{k + 1}}{k + 1} \dbinom{m + 1}{k} \sum_{j = 0}^{m - k} \dbinom{m - k + 1}{j} B_j + (m + 1) \Delta \]又根據伯努利數的遞迴定義
\[\sum_{k = 0}^m \dbinom{m + 1}{k} B_k = [m = 0] \]\[\begin{aligned} n^{m + 1} & = \sum_{k = 0}^m \dfrac{n^{k + 1}}{k + 1} \dbinom{m + 1}{k} [m - k = 0] + (m + 1) \Delta \\ & = \dfrac{n^{m + 1}}{m + 1} \dbinom{m + 1}{m} + (m + 1) \Delta \\ & = n^{m + 1} + (m + 1) \Delta \end{aligned} \]啊哈!至此,我們推出了
\[(m + 1) \Delta = 0 \\ \because m + 1 \ne 0 \\ \therefore \Delta = 0 \]證完嘍!
當然,還有一種用 指數生成函式 的更簡單的證明方法,因為筆者才疏學淺不會生成函式就先不證了,到時候在生成函式的筆記裡證(
程式碼實現
顯然這東西一般用在有模數的情況下。
//18 = 9 + 9 = 18.
#include <iostream>
#include <cstdio>
#define Debug(x) cout << #x << "=" << x << endl
typedef long long ll;
using namespace std;
const int MAXN = 1e4 + 5;
const int N = 1e4;
const int MOD = 1e9 + 7;
int add(int a, int b) {return (a + b) % MOD;}
int mul(int a, int b) {return (ll)a * b % MOD;}
int inv[MAXN], C[MAXN][MAXN], B[MAXN];
int main()
{
freopen("mango.out", "w", stdout);
for (int i = 0; i <= N; i++)
{
C[i][0] = C[i][i] = 1;
}
for (int i = 1; i <= N; i++)
{
for (int j = 1; j < i; j++)
{
C[i][j] = add(C[i - 1][j], C[i - 1][j - 1]);
}
}
inv[1] = 1;
for (int i = 2; i <= N; i++)
{
inv[i] = mul(MOD - MOD / i, inv[MOD % i]);
}
B[0] = 1;
for (int m = 1; m <= N; m++)
{
int sum = 0;
for (int k = 0; k < m; k++)
{
sum = add(sum, mul(C[m + 1][k], B[k]));
}
B[m] = mul(MOD - sum, inv[m + 1]);
}
for (int i = 1; i <= 10000; i++)
{
printf("%d\n", B[i]);
}
return 0;
}