【学习笔记】数论之生成函数基础

发布时间 2023-07-26 15:28:42作者: linyihdfj

前言

一直不是很会生成函数,但是平常遇到的数论题,很多地方都是会用到生成函数,现在正好有了时间可以搞一搞
未来说不定会补上 NTT。

FFT

(下文极有可能有一些加一减一的不合理的地方,可能以后会修修)
如果不会 FFT 那么生成函数肯定就完全做不了题了。(写过一篇不过当时根本不理解,胡写的太垃圾了)
考虑这样的一个问题:给定两个多项式 \(A(x) = a_0 + a_1x + a_2x^2 + ... + a_{n-1}x^{n-1}\)\(B(x) = b_0 + b_1x + b_2x^2 + ... + b_{m-1}x^{m-1}\),求他们的积。
如果只是暴力地做这个问题的话需要 \(O(nm)\) 的复杂度就爆炸了。
但是我们知道,多项式除了系数表示还有点值表示,下面认为 \(n = m\) 因为显然可以用 \(0\) 补位,不妨假设 \(A\) 的点值表示为 \((x_0,A(x_0))(x_1,A(x_1))...(x_n,A(x_n))\)\(B\) 的点值表示为 \((x_0,B(x_0))(x_1,B(x_1))...(x_n,B(x_n))\),则设 \(C = A \times B\),则显然可得 \(C\) 的点值表示为 \((x_0,A(x_0)B(x_0))(x_1,A(x_1)B(x_1))...(x_n,A(x_n)B(x_n))\)
而我们知道 \(n\) 个不重的点可以唯一确定一个 \(n-1\) 次多项式,而我们 \(C\) 可以理解为一个 \(n+m\) 次多项式,所以我们只需要找到 \(n+m+1\) 个点将 \(A,B\) 均转化为点值表示然后得到 \(C\) 的点值表示,再将点值表示转化为系数表示就好了。

下面问题就转化为了给定一个多项式 \(A(x) = a_0 + a_1x + a_2x^2 + ... + a_{n-1}x^{n-1}\) 如何求出它的点值表示。
点值表示关键就在于选择哪些点来表示,经过前人可以知道我们选择复数域上的 \(n\) 次单位根就满足十分优良的性质。

这里就要介绍一下复数域上的单位根是什么东西(不理解可以自己百度百科):
形如 \(a + bi\) 的数就被称为复数,其中 \(i = \sqrt{-1}\)
复数相加就相当于在复平面上两个向量相加,结果为它们形成的平行四边形的对角线。
复数相乘在复平面上相当于长度相乘,俯角相加。
而单位根就要引入单位圆的概念,单位圆就是与原点距离为 \(1\) 的点构成的集合,而 \(n\) 次单位根是指的将单位圆分成 \(n\) 份后得到的 \(n\) 个向量,第 \(i\) 个向量我们记为 \(w_n^i\),特别的 \(w_n^0 = (1,0)\)
如下图所示为一个 \(8\) 次单位根:

根据图像我们可以得到单位根的一些性质,而且只要满足某些关键性质的数理论上都可以作为我们选择的点:

  1. \(\forall i \not= j,w_n^i \not= w_n^j\)
  2. \(w_n^k = \cos(\frac{2\pi}{n}k) + i\sin(\frac{2\pi}{n}k)\)
  3. \(w_{n}^n = w_{n}^0 = 1\)
  4. \(w_{2n}^{2k} = w_{n}^k\)
  5. \(w_{n}^{k+\frac{n}{2}} = -w_{n}^k\)

上述性质的证明放在复平面上显然,就不多写了。

这个知识知道了我们就考虑开始化简给定的多项式,第一步就是按奇偶分类,设:

\[A_1(x) = a_0 + a_2x + a_4x^2 + ... + a_{n-2}x^{\frac{n}{2}-1}\\ A_2(x) = a_1 + a_3x + a_5x^2 + ... + a_{n-1}x^{\frac{n}{2}-1} \]

\(A(x) = A_1(x^2) + xA_2(x^2)\),考虑将单位根带入,这里注意我们只需要枚举 \(k \in [0,\frac{n}{2}-1]\) 因为另一半可以直接在这个基础上加 \(\frac{n}{2}\) 得到。

\[A(w_n^k) = A_1(w_n^{2k}) + w_n^kA_2(w_n^{2k}) = A_1(w_{\frac{n}{2}}^k) + w_n^kA_2(w_{\frac{n}{2}}^k) \\ A(w_n^{k+\frac{n}{2}}) = A_1(w_n^{2k}) - w_n^kA_2(w_n^{2k}) = A_1(w_{\frac{n}{2}}^k) - w_n^kA_2(w_{\frac{n}{2}}^k) \]

发现这其实就是一个递归下去的子问题,递归树可知复杂度为 \(O(n \log n)\)

下面就是考虑给定一个多项式的点值表示怎么转化为系数表示,此时给定的点值表示一定为 \((w_n^i,A(w_n^i))\),为了下文方便我们直接令 \(A(w_n^i) = y_i\),设:

\[C_k = \sum_{i=0}^{n-1}y_i(w_n^{-k})^i \]

可以发现的一点是 \(a_i = C_i \times n\),所以只要我们可以快速求出 \(C\) 我们就可以得到 \(A\) 的系数表示。
\(y_i\) 视为已知数,构造:

\[B(x) = y_0 + y_1x + y_2x^2 + ... + y_{n-1}x^{n-1} \]

则有:

\[C(k) = B(w_n^{-k}) \]

也就是说我们要求出 \(B\) 这个多项式在 \(n\) 次单位根的相反数位置的值,也就是和我们上述解决的问题多了一个负号,可以证明的是这两种方式可以套用同一个解决方法,完全等价。
现在其实就差了一个问题就是为什么 \(a_i = C_i \times n\),下面就给出证明过程:

\[C_k = \sum_{i=0}^{n-1}(\sum_{j=0}^{n-1}a_j(w_n^i)^j)(w_n^{-k})^i \\ = \sum_{i=0}^{n-1}(\sum_{j=0}^{n-1}a_j(w_n^j)^i)(w_n^{-k})^i \\ = \sum_{j=0}^{n-1}a_j\sum_{i=0}^{n-1} (w_{n}^{j-k})^i \]

在内层求和中 \(j-k\) 是不会改变的,所以考虑构造:

\[S(x) = 1 + x + ... + x^{n-1} \]

则:

\[S(w_n^k) = 1 + w_n^k + ... + (w_n^k)^{n-1} \]

此时分类讨论。
\(k \not= 0\),则:

\[w_n^kS(w_n^k) = w_n^k + (w_n^k)^2 + ... + (w_n^k)^n = w_n^k + (w_n^k)^2 + ... + 1 \]

所以:

\[(1 - w_n^k)S(w_n^k) = 0 \]

因为 \(k \not= 0\) 所以 \(1 - w_n^k \not= 0\)\(S(w_n^k) = 0\)
\(k = 0\),则:

\[S(w_n^k) = n \]

所以只有当 \(j - k = 0\)\(j = k\) 时式子内部的和不为 \(0\),也就是 \(C_k = a_k \times n\)

至此我们的 FFT 就完结撒花了(吗?)
我们会发现这是一个递归的版本实际运行效率极慢,所以要考虑换成迭代的版本。
因为我们每一次都会执行奇偶分类的操作所以我们也必须得到操作后的序列才能自底向上合并,手动模拟一下结果就如下图所示:

可以发现如果我们的 \(n\) 不为 \(2\) 的整数次幂那么这些操作就很难进行,所以就可以使用 \(0\) 补齐。将第 \(i\) 位经过操作后的位置记为 \(rev[i]\),那么在二进制下 \(rev[i]\) 就是 \(i\) 的翻转。
具体求解 \(rev[i]\) 可以考虑将二进制下最后一位拿出来,得到剩下的位翻转的结果,然后再将最后一位放到最前面。
代码:

点击查看代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;

const int N = 300010;
const double PI = acos(-1);

int n, m;
struct Complex
{
    double x, y;
    Complex operator+ (const Complex& t) const
    {
        return {x + t.x, y + t.y};
    }
    Complex operator- (const Complex& t) const
    {
        return {x - t.x, y - t.y};
    }
    Complex operator* (const Complex& t) const
    {
        return {x * t.x - y * t.y, x * t.y + y * t.x};
    }
}a[N], b[N];
int rev[N], bit, tot;

void fft(Complex a[], int inv)
{
    for (int i = 0; i < tot; i ++ )
        if (i < rev[i])
            swap(a[i], a[rev[i]]);
    for (int mid = 1; mid < tot; mid <<= 1)
    {
        auto w1 = Complex({cos(PI / mid), inv * sin(PI / mid)});
        for (int i = 0; i < tot; i += mid * 2)
        {
            auto wk = Complex({1, 0});
            for (int j = 0; j < mid; j ++, wk = wk * w1)
            {
                auto x = a[i + j], y = wk * a[i + j + mid];
                a[i + j] = x + y, a[i + j + mid] = x - y;
            }
        }
    }
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i <= n; i ++ ) scanf("%lf", &a[i].x);
    for (int i = 0; i <= m; i ++ ) scanf("%lf", &b[i].x);
    while ((1 << bit) < n + m + 1) bit ++;
    tot = 1 << bit;
    for (int i = 0; i < tot; i ++ )
        rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (bit - 1));
    fft(a, 1), fft(b, 1);
    for (int i = 0; i < tot; i ++ ) a[i] = a[i] * b[i];
    fft(a, -1);
    for (int i = 0; i <= n + m; i ++ )
        printf("%d ", (int)(a[i].x / tot + 0.5));

    return 0;
}

这样我们通往生成函数的第一大关就算结束啦。

生成函数入门

本篇只讲解一些基础知识即入门所以很多地方注重理解不注重严谨,进阶的可能以后会有。

首先就是要知道什么是生成函数,以及它可以干什么。
生成函数名字很高级,其实本质它就是多项式,也就是给定一个任意序列 \(a_0,a_2,...,a_n,...\),我们将其作为多项式的系数带入到多项式当中即变成 \(A(x) = a_0 + a_1x + \cdots a_nx^n + \cdots\),在生成函数中我们默认 \(-1 < x < 1\),所以其实就是一个序列和多项式的映射。
我们为什么要有这种映射呢,毕竟映射不一定可以简化问题。因为我们对于多项式的研究十分深入,可以使用各种多项式的手段解决这个问题。
对于生成函数解决的一般问题就是求方案数的问题,这类问题一般我们都会采取乘法原理什么的来解决,可以发现的是乘法原理本质上就是多项式的乘法,所以就可以转化为多项式问题了。
下面以一个例题来感受一下这个过程是什么:

题目描述:
有三个砝码重量分别为 \(1g、2g、3g\) 每个砝码可以选或者不选,询问能够组成的重量有多少种。

我们考虑将 \(a_i\) 定义为组成的重量为 \(i\) 的方案数,考虑对于每一个砝码求出其生成函数,直接将生成函数乘起来就是答案。设 \(f_i\) 表示第 \(i\) 个砝码的生成函数则有:

\[\begin{aligned} &f_1(x) = 1 + x \\ &f_2(x) = 1 + x^2 \\ &f_3(x) = 1 + x^3 \\ \end{aligned} \]

\(f(x)\) 表示最终的答案,则:

\[\begin{aligned} f(x) &= f_1(x)f_2(x)f_3(x) \\ &= (1+x)(1+x^2)(1+x^3) \\ &= 1 + x + x^2 + 2x^3 + x^4 + x^5 + x^6 \end{aligned} \]

我们发现多项式乘法其实就是乘法原理,也就是我们看每个砝码究竟是选还是不选然后继续向下。
这样可能就对生成函数有点感觉了,下面再来一道题加深一下印象吧。

题目描述:
有三个砝码重量分别为 \(1g、2g、3g\),重量为 \(1g\) 的砝码有两个,重量为 \(2g\) 的砝码有无限个,重量为 \(3g\) 的砝码有 \(1\) 个,每个砝码可以不选也可以选任意多个,询问组成重量为 \(4\) 的方案数有多少种。

依旧是上述的套路:

\[\begin{aligned} &f_1(x) = 1 + x + x^2 \\ &f_2(x) = 1 + x^2 + x^4 + ...\\ &f_3(x) = 1 + x^3 \end{aligned} \]

则:

\[f(x) = f_1(x)f_2(x)f_3(x) \]

自己枚举一下就会发现,方案数总共有 \(3\) 种。

下面就是一道生成函数的入门典题了

题目描述:
\(m\) 个物品,每种物品有无限个,询问从中选择 \(k\) 个的方案数有多少种。

根据我们已知的组合数学常识,可以直接插板法解决,这个问题即求

\[x_1 + x_2 + ... + x_m = k (x_i \ge 0) \]

的解的个数,但是插板法只可以解决 \(x_i \ge 1\) 的情况,那么就强制每个多 \(1\) 就可以了,就转化为:

\[x_1 + x_2 + ... + x_m = k + m (x_i \ge 1) \]

这个问题就是 \(k+m\) 个球放到 \(m\) 个盒子里面,也就是在 \(k+m\) 个球之间\(m-1\) 个板的方案数,答案即:

\[\binom{k+m-1}{m-1} \]

下面考虑怎么使用生成函数解决这个问题:
第一步显然是构造每一个物品的生成函数,此时的 \(a_i\) 其实就是相当于选择 \(i\) 个的方案数:

\[f_i(x) = 1 + x + x^2 + ... = \dfrac{1-x^n}{1-x}= \dfrac{1}{1-x} \]

上述过程因为 \(n \to \infty\)\(-1 < x < 1\),所以 \(x^n \to 0\) 所以可以直接省略,其实上述也代表了我们生成函数里的一个重要等式:

\[1 + x^p + x^{2p} + ... = \dfrac{1}{1-x^p} \]

那么我们答案的生成函数就是:

\[f(x) = \prod_{i=1}^mf_i(x) = \dfrac{1}{(1-x)^m} \]

这个东西我们是不会展开的,但是我们根据组合意义推到了这个东西的展开形式:

\[f(x) = \dfrac{1}{(1-x)^m} = \binom{0+m-1}{m-1} + \binom{1+m-1}{m-1}x + \binom{2+m-1}{m-1}x^2 + ... \]

也就是我们得到了这样一个重要的展开:

\[\dfrac{1}{(1-x)^m} = \sum_{i=0}^{\infty} \binom{i+m-1}{m-1} x^i \]

这个形式比较丑陋,换个形式就好看多了:

\[\dfrac{1}{(1-x)^{m+1}} = \sum_{i=0}^{\infty} \binom{i+m}{i}x^i \]

最后再看一道生成函数的真实题目,我们的生成函数就算是成功入门了。

题目描述:
给定 \(8\) 个物品,每个物品选择的限制如下,询问恰好选择 \(n\) 个的方案数并对 \(10007\) 取模,\(1 \le n \le 10^{500}\)
1.第一个物品必须选择偶数个
2.第二个物品选择 \(0\) 个或 \(1\)
3.第三个物品选择 \(0\) 个、\(1\) 个或 \(2\)
4.第四个物品选择奇数个
5.第五个物品选择 \(4\) 的倍数个
6.第六个物品选择 \(0\) 个、\(1\) 个、\(2\) 个或 \(3\)
7.第七个物品选择 \(0\) 个或 \(1\)
8.第八个物品选择 \(3\) 的倍数个

第一步就是将每个物品对应的生成函数求出来:

\[\begin{aligned} &f_1(x) = 1 + x^2 + x^4 + ... = \dfrac{1}{1-x^2} \\ &f_2(x) = 1 + x = \dfrac{1-x^2}{1-x} \\ &f_3(x) = 1 + x + x^2 = \dfrac{1-x^3}{1-x} \\ &f_4(x) = x + x^3 + x^5 + ... = \dfrac{x}{1-x^2} \\ &f_5(x) = 1 + x^4 + x^8 + ... = \dfrac{1}{1-x^4} \\ &f_6(x) = 1 + x + x^2 + x^3 = \dfrac{1-x^4}{1-x} \\ &f_7(x) = 1 + x = \dfrac{1-x^2}{1-x} \\ &f_8(x) = 1 + x^3 + x^6 + ... = \dfrac{1}{1-x^3}\\ \end{aligned} \]

下面就是愉快的消消乐环节了:

\[f(x) = f_1(x)f_2(x)f_3(x)f_4(x)f_5(x)f_6(x)f_7(x)f_8(x) = \dfrac{x}{(1-x)^4} = x (\sum_{i=0}^{\infty} \binom{i+3}{3}x^i) = \sum_{i=0}^{\infty} \binom{i+3}{3}x^{i+1} \]

答案就是 \(x^n\) 的系数,即:

\[\binom{n+2}{3} = \dfrac{(n+2)(n+1)n}{6} \]

生成函数入门完结撒花,下面就是一些更为深入和具体的东西啦。

OGF

基础知识

OGF 全称为 \(\text{oridinary generating function}\) 也就是普通生成函数,这个东西的定义与我们上文的生成函数入门里讲的是一致的。
对于一个序列 \(a_1,a_2,...,a_n,...\),它的 OGF 即 \(f(x) = a_0 + a_1x + a_2x^2 + ... + a_nx^n + ...\)
对于生成函数我们常用的方法就是构造封闭形式,也就是上文中提到的那些看上去特别简洁的式子,这里给出几个常见的封闭形式,下文就围绕这几个封闭形式展开:

\[\begin{aligned} &f(x) = 1 + x + x^2 + x^3 + ... = \dfrac{1}{1-x} \\ &f(x) = 1 + ax + a^2x^2 + a^3x^3 + ... = \dfrac{1}{1-ax} \\ &f(x) = \sum_{i=0} x^{ik} = \dfrac{1}{1-x^k} \\ &f(x) = \sum_{i=0} c^ix^{ik} = \dfrac{1}{1-cx^k} \\ &f(x) = \binom{n}{0}x^0 - \binom{n}{1}x^1 + \binom{n}{2}x^2 - \binom{n}{3}x^3 + ... + \binom{n}{n}x^n= (1-x)^n \\ &f(x) = \binom{n}{0}x^0 + \binom{n+1}{1}x^1 + \binom{n+2}{2}x^2 + ... = \dfrac{1}{(1-x)^{n+1}} \end{aligned} \]

第五个式子就是二项式定理展开,其他的都在上述入门的讲解里面推导过。
除了这些还有两个不会证明的形式:

\[\begin{aligned} &f(x) = 0 + x + \frac{1}{2}x^2 + \frac{1}{3}x^3 + ... = \ln \frac{1}{1-x} = -\ln(1-x) \\ &f(x) = 1 + x + \frac{1}{2!}x^2 + \frac{1}{3!}x^3 + ... = e^x \end{aligned} \]

OGF 的乘法就比较有意思的(下文中 \(A[i]\) 代表第 \(i\) 项的系数):
\(C = A * B\),则有:\(C[x] = \sum_{i+j=x}A[i]B[j]\),所以其实这个东西就是加法卷积或者叫做计数背包。
所以其实此时重新回顾一下我们入门中讲解的知识,其实就是因为 OGF 的乘法可以理解为加法卷积,所以我们可以单独构造然后乘起来就是答案。
基础知识大概就这些了,下面就是一些 OGF 的应用啦。

斐波那契数列

第一步当然就是推导大名鼎鼎的斐波那契数列的通项公式了。
斐波那契数列的定义为 \(a_0 =0,a_1 = 1,a_i = a_{i-1} + a_{i-2}(i \ge 2)\),设它的 OGF 为 \(f(x)\),则根据定义显然:

\[f(x) = a_0 + a_1x + a_2x^2 + ... \]

考虑想一些办法让 \(f(x)\) 表示自己,也就是错位一下看看:

\[\begin{aligned} f(x) &= a_0 + &a_1x + a_2x^2 + a_3x^3 + ... \\ xf(x) &= &a_0x + a_1x^2 + a_2x^3 + ... \\ x^2f(x) &= & a_0x^2 + a_1x^3 + ... \\ \end{aligned} \]

可以显然发现当次数大于等于 \(2\)\(xf(x)\) 的系数和 \(x^2f(x)\) 的系数和为 \(f(x)\) 的系数,次数小于等于 \(1\) 的项可以手动修正:

\[f(x) - xf(x) - x^2f(x) = x \]

解得:

\[f(x) = \dfrac{x}{1 - x - x^2} \]

感觉这一步比较神仙,就是因为我们已知的东西根本推不出来这个,就想办法把这个转化到已知的上面即我们认为下面这个方程一定有解:

\[\dfrac{A}{1-ax} + \dfrac{B}{1-bx} = \dfrac{x}{1-x-x^2} \]

通分:

\[\dfrac{(A - Abx + B - aBx)}{(1-ax)(1-bx)} = \dfrac{x}{1 - x - x^2} \]

系数对应相等:

\[\begin{cases} A + B = 0\\ -Ab - aB = 1 \\ a + b = 1 \\ ab = -1 \\ \end{cases} \]

解的:

\[\begin{cases} A = \dfrac{1}{\sqrt{5}} \\ B = -\dfrac{1}{\sqrt{5}} \\ a = \dfrac{1 + \sqrt{5}}{2} \\ b = \dfrac{1 - \sqrt{5}}{2} \\ \end{cases} \]

带入后把封闭形式展开就得到了斐波那契数列通项公式:

\[\dfrac{x}{1-x-x^2} = \sum_{i=0}^{\infty}x^i\dfrac{1}{\sqrt{5}}\big[(\dfrac{1+\sqrt{5}}{2})^i - (\dfrac{1-\sqrt{5}}{2})^i\big] \]

卡特兰数

卡特兰数的应用十分广泛,例如:

  • 长度为 \(n\) 的仅包含小括号的合法括号序列数
  • 节点个数为 \(n\) 的二叉树个数
  • \(n\times n\) 的网格图上,不跨越(并非不可触碰)对角线地从 \((1,1)\) 走到 \((n,n)\) 地方案数。

其部分序列为:

\(H_0\) \(H_1\) \(H_2\) \(H_3\) \(H_4\) \(\cdots\)
1 1 2 5 14 \(\cdots\)

卡特兰数显然满足如下递推式:

\[H_n = \sum_{i=0}^{n-1}H_i H_{n-i-1} (n \ge 2) \]

其中 \(H_0 = 1,H_1 = 1\)
如果以括号序列来理解就是枚举最后块内部选择多少个。
下面就是想办法求解这个序列对应的 OGF 的封闭形式,在求之前要先引入一个新的定理,广义二项式定理:
重新定义组合数运算为:

\[\binom{n}{m} = \dfrac{n^{\underline{m}}}{m!} (n \in \mathbb{C},m\in\mathbb{R}) \]

注意的是此时 \(n\) 在复数域上,那么对于 \(a \in \mathbb{C}\) 都有:

\[(1+x)^a = \sum_{i=0}^{\infty} \binom{a}{i} x^i \]

对于卡特兰数的递推式观察会发现很像卷积,所以考虑能不能用卷积构造:

\[f(x) = \sum_{i=0}^{\infty} H_i x^i = 1 + \sum_{i=1}^{\infty}\sum_{j=0}^{i-1} H_jx^jH_{n-j-1}x^{n-j-1}x = 1 + x\sum_{i=0}^{\infty} H_ix^i \sum_{j=0}^{\infty} H_jx^j = 1 + xf^2(x) \]

这就是一个一元二次方程,解得:

\[f(x) = \dfrac{1\pm\sqrt{1-4x}}{2x} \]

则显然应取:

\[f(x) = \dfrac{1 - \sqrt{1-4x}}{2x} \]

根据广义二项式定理得:

\[(1-4x)^{\frac{1}{2}} = \sum_{i=0}^{\infty} \binom{\frac{1}{2}}{i}(-4x)^i = \sum_{i=0}^{\infty} \dfrac{(\frac{1}{2})^{\underline{i}}}{i!}(-4x)^i \]

考虑化简 \((\frac{1}{2})^{\underline{n}}\)

\[(\frac{1}{2})^{\underline{n}} = \frac{1}{2} \times \frac{-1}{2} \times \frac{-3}{2} \times \cdots \times \frac{-(2n-3)}{2} = \dfrac{(-1)^{n-1}(2n-3)!!}{2^n} = \dfrac{(-1)^{n-1}(2n-2)!}{2^n(2n-2)!!} = \dfrac{(-1)^{n-1}(2n-2)!}{2^{2n-1}(n-1)!} \]

上述推导涉及两个双阶乘的化简技巧:

\[n!! = \dfrac{(n-1)!}{(n-1)!!} \\ (2n)!! = 2^n n! \]

考虑把我们得到的式子带入原式:

\[(1 - 4x)^{\frac{1}{2}} = 1 + \sum_{i=1}^{\infty} \dfrac{(-1)^{i-1}(2i-2)!}{i!(i-1)!2^{2i-1}}(-4x)^i = 1 - \sum_{i=1}^{\infty}\dfrac{(2i-2)!}{i!(i-1)!}2x^i = 1 - \sum_{i=1}^{\infty} \binom{2i-1}{i} \dfrac{1}{2i-1} 2x^i \]

继续把这个式子带回去:

\[f(x) = \dfrac{1-\sqrt{1-4x}}{2x} = \dfrac{1}{2x}\sum_{i=1}^{\infty}\binom{2i-1}{i}\dfrac{1}{2i-1}2x^i = \sum_{i=1}^{\infty} \binom{2i-1}{i} \dfrac{1}{2i-1}x^{i-1} = \sum_{i=0}^{\infty} \binom{2i+1}{i+1}\dfrac{1}{2i+1}x^i = \sum_{i=0}^{\infty}\binom{2i}{i}\dfrac{1}{i+1}x^i \]

也就是成功得到了通项公式,即:

\[H_n = \binom{2n}{n}\dfrac{1}{n+1} \]

OGF 的基础部分就先告一段落了,有没有进阶部分就以后再说吧。