多项式乘法
问题背景
给定两个多项式 和 :
我们需要计算它们的乘积 。
根据定义,乘积 的系数 为:。这个形式的计算被称为卷积。如果我们直接按照这个定义进行计算,对于 的每一项系数,都需要 的时间。由于 的最高次项为 ,总的时间复杂度为 ,通常简记为 。当 和 的规模达到 甚至更大时,这种朴素算法显然无法接受。
加速计算的思路:点值表示法
我们知道,一个 次多项式可以被 个不同的点唯一确定。例如,一条直线(1 次多项式)可以被两个点唯一确定,一条抛物线可以被三个点唯一确定。
这启发我们,除了用系数表示多项式,还可以用点值来表示。
- 系数表示法:
- 点值表示法:给定 个不同的数 ,计算出 ,则多项式 可以用点对集合 来表示。
点值表示法的优势在于乘法运算。如果 ,那么对于任意一个 ,显然有 。因此,如果 和 都在一组相同的点 上求值,我们就可以在 的时间内计算出 在这些点上的点值。
这给了我们一个全新的计算流程:
- 求值(Evaluation):选择 个点,分别计算出 和 在这些点上的点值。
- 点积(Pointwise Product):将 和 的点值对应相乘,得到 的点值。
- 插值(Interpolation):根据 的点值,反解出它的系数。
这个思路的关键在于如何快速地完成第一步(求值)和第三步(插值)。如果随机选取点,求值过程的复杂度依然是 。因此,我们需要找到一组特殊的点,使得求值和插值可以被加速。
快速傅里叶变换(FFT)
快速傅里叶变换(Fast Fourier Transform, FFT)就是实现上述快速求值和插值的关键算法。它巧妙地选取了一组特殊的复数——单位根,作为求值的点。
复数与单位根
- 复数:形如 的数,其中 是实部, 是虚部, 是虚数单位,满足 。复数可以在复平面上表示,对应坐标为 。
- 欧拉公式:。这建立了指数函数和三角函数之间的桥梁,几何意义是复平面上一个模长为 1,与正实轴夹角为 的向量。
- 次单位根:满足方程 的复数解 。根据欧拉公式,这些解恰好有 个,它们是:其中 表示第 个 次单位根。
单位根在复平面上均匀地分布在一个单位圆上,它们把圆 等分。

单位根的性质:
- 周期性:
- 对称性:(当 为偶数)
- 折半引理:(当 为偶数)
1.3.2 FFT 的分治思想
FFT 的核心思想是分治。假设我们要对一个 次多项式 在 个单位根 上求值(这里假定 是 2 的幂,不足则高位补 0)。
我们将 按系数的奇偶性分成两部分:
令
则有
现在,我们要在 处求值:
利用折半引理 ,上式变为:
对于 的情况:
利用周期性和对称性 和 ,上式变为:
我们发现,计算 和 所需的子问题 和 是完全相同的!
这意味着,一个规模为 的问题,可以被分解为两个规模为 的子问题,外加 的合并操作。这正是分治法的结构。其时间复杂度为:
逆变换(IFFT)
求值过程(也称为离散傅里叶变换,DFT)的逆过程——插值,可以通过逆离散傅里叶变换(IDFT)完成。可以证明,IDFT 的计算过程与 DFT 惊人地相似。
如果一个序列 是序列 的 DFT,那么:
这表明,IDFT 除了主元(单位根)从 变成了它的共轭复数 ,并且最后结果需要除以 之外,其余计算过程和 DFT 完全一样。因此,我们可以复用 FFT 的代码来实现 IFFT。
模板题
P3803 【模板】多项式乘法(FFT) - 洛谷
快速数论变换(NTT)
FFT 虽然快,但有一个致命弱点:浮点数精度误差。在处理系数很大或者需要取模的题目时,FFT 会因为精度问题得到错误答案。
快速数论变换(Number Theoretic Transform, NTT)是 FFT 在模数域上的变种,它使用原根替代单位根,从而在整数环内完成变换,完全避免了精度问题。
- 原根:在一个模 的整数环中,如果一个整数 满足 ()的结果互不相同,则称 是模 的一个原根。
- NTT 的条件:NTT 的存在需要模数 是一个质数,且 必须是 的倍数,其中 是变换的长度(通常是 2 的幂)。即 的形式。
- NTT 中的“单位根”:我们取 作为 次“单位根” 。可以证明,它在模 意义下拥有和复数单位根完全相同的性质,从而可以执行与 FFT 相同的分治算法。
常用的 NTT 模数:
NTT 的代码实现与 FFT 非常相似,只需将复数运算替换为模意义下的整数运算即可。
生成函数
生成函数(Generating Function),又称母函数,是组合数学中一个强大的工具。它将一个无限序列 与一个函数(形式幂级数)关联起来,通过对函数进行代数运算,来解决序列相关的问题(通常是计数问题)。
普通生成函数(OGF)
对于序列 ,其普通生成函数(Ordinary Generating Function, OGF)定义为:
这里的 是一个形式变量,我们只关心它的系数。
基本例子:
- 序列 的 OGF 是 。
- 序列 的 OGF 是 。
- 有限序列 (共 项)的 OGF 是 。
核心思想:生成函数的强大之处在于,组合问题的“相加”和“相乘”规则,可以对应到生成函数的“相加”和“相乘”运算上。
- 加法法则:如果一个问题可以分为互斥的 A 和 B 两类,那么总方案数的生成函数等于 A 类方案的生成函数与 B 类方案的生成函数之和。
- 乘法法则:如果一个问题可以分为独立的 A 和 B 两个步骤,总方案数的生成函数等于 A 步骤方案的生成函数与 B 步骤方案的生成函数之积。
应用举例:背包问题。假设有两类物品,第一类物品的体积为 2,有无限件;第二类物品的体积为 3,有无限件。问装满容量为 的背包有多少种方案?
- 第一类物品的生成函数(体积作为 的指数):
- 第二类物品的生成函数:
根据乘法法则,总方案的生成函数为:
展开后 的系数,就是装满容量为 的背包的方案数。这个系数可以通过多项式求逆等操作(依赖于 NTT)来求得。
斐波那契数列的生成函数
斐波那契数列定义为 for 。
令其生成函数为 。
根据递推关系:
解出 :
通过将这个有理分式展开成幂级数,我们可以得到斐波那契数列的通项公式。这展示了生成函数在解决递推关系上的威力。