多项式卷积 FFT 和 NTT

FFT

多项式

定义

多项式是形如 A(x)=i=0nai×xiA(x) = \sum_{i = 0}^n a_i \times x_i 的表达式,其中 xx 为不定元,这是多项式的系数表示法。

将多项式中不定元的最大次数称为多项式的次数,记做 (A(x))\partial(A(x))

运算

A(x)=i=0naixi,B(x)=i=0mbixi A(x)±B(x)=i=0max{n,m}(ai±bi)xi A(x)×B(x)=i=0nj=0m(ai×bj)xi+j=k=0n+mi=0n(ai×bki)xk \begin{array}{c} A(x)=\sum_{i=0}^{n} a_{i} x^{i}, B(x)=\sum_{i=0}^{m} b_{i} x^{i} \\ \ \\ A(x) \pm B(x)=\sum_{i=0}^{\max \{n, m\}}\left(a_{i} \pm b_{i}\right) x^{i} \\ \ \\ A(x) \times B(x)=\sum_{i=0}^{n} \sum_{j=0}^{m}\left(a_{i} \times b_{j}\right) x^{i+j} \\ =\sum_{k=0}^{n+m} \sum_{i=0}^{n}\left(a_{i} \times b_{k-i}\right) x^{k} \end{array}

多项式乘法满足交换律,结合律和分配率。

多项式的除法通常指带余除法。

A(x)=q(x)B(x)+r(x)(r(x))<(B(x)) A(x)r(x)(modB(x)) A(x) = q(x)B(x)+r(x) \quad \partial(r(x)) < \partial(B(x)) \\ \ \\ A(x) \equiv r(x) \quad(\bmod B(x))

q(x)q(x) 称为 B(x)B(x)A(x)A(x) 的商式,r(x)r(x) 称为 B(x)B(x)A(x)A(x) 的余式。若 r(x)=0r(x)=0,则称 B(x)B(x) 整除 A(x)A(x),记作 B(x)A(x)B(x)|A(x)

点值表示法

nn 个点可以确定唯一的 n1n-1 次多项式。如果多项式 f(x)f(x)g(x)g(x) 的次数不超过 nn,且对于 n+1n+1 个不同的数都有相同的对应值,则 f(x)=g(x)f(x) = g(x)

如果选取 n+1n+1 个不同的数,x0xnx_0 \sim x_n 对多项式求职,得到 A(x0),A(x1),,A(xn)A(x_0), A(x_1), \cdots, A(x_n)。那么称 {(xi,A(xi)0in,iN}\{ (x_i,A(x_i) | 0 \leq i \leq n, i \in\mathbb{N}\} 为多项式 A(x)A(x) 的点值表示。通过系数表示求点值表示的过程叫做求值,通过点值表示求系数表示的过程叫做插值。

A(x)A(x)B(x)B(x) 是两个多项式,它们在 x0snx_0 \sim s_n 上的取值分别为 c0cnc_0 \sim c_nD0DnD_0 \sim D_n。那么 A(x)×B(x)A(x) \times B(x)x0,x1,,xnx_{0}, x_{1}, \ldots, x_{n} 上的取值分别为 c0D0cnDnc_{0} D_{0} \sim c_n D_n

复数

  • 定义

虚数单位 i=1i=\sqrt{-1}

形如 a+bi(a,bR)a + b_i (a, b \in \mathbb{R}) 的数称为复数,aa 称为实部,bb 称为虚部。全体复数的集合记为 C\mathbb{C}

  • 运算

z=a+bi,w=c+diz = a + bi, w = c+di,有

z±w=(a±c)+(b±d)i z×w=ac+adi+bci+bdi2=(acbd)+(ad+bc)i z÷w=a+bic+di=(a+bi)(cdi)(c+di)(cdi)=(ac+bd)+(bcad)ic2+d2 z \pm w=(a \pm c)+(b \pm d) i \\ \ \\ z \times w=a c+a d i+b c i+b d i^{2}=(a c-b d)+(a d+b c) i \\ \ \\ z \div w=\frac{a+b i}{c+d i}=\frac{(a+b i)(c-d i)}{(c+d i)(c-d i)}=\frac{(a c+b d)+(b c-a d) i}{c^{2}+d^{2}}

复数的相加满足平行四边形法则。

多项式卷积 FFT 和 NTT

共轭复数:z=abi\overline{z}=a-b i,相当于对虚部取反。

  • 几何意义

令横轴为实轴,纵轴为虚轴。复数 a+bia+bi 就对应坐标为 (a,b)(a,b) 的点或向量。

复数对应的点到原点的距离称为复数的模长,记为 r=zr=|z|。 由勾股定理 z=a2+b2=zz|z|=\sqrt{a^{2}+b^{2}}=\sqrt{z \overline{z}}

复数与实轴正半轴形成的角称为复数的辐角,记为 φ=argz\varphi=\arg z

复数也可以用模长和辐角表示,称为复数的极坐标形式。由极坐标与直角坐标的转化关系,z=r(cosφ+isinφ)z=r(\cos \varphi+i \sin \varphi)

多项式卷积 FFT 和 NTT
复数的乘法,按照模长相乘,辐角相加的运算规则。除法为乘法的逆运算。

复数的共轭,则为复数对应向量与实轴轴对称的结果。

单位根

欧拉公式

对于任意实数 xx,都有

eix=cosx+isinx e^{i x}=\cos x+i \sin x

证明略。这个公式可以说明当 xx 为实数时,函数 f(x)=eixf(x) = e^{ix} 可以再复数屏幕表述一个单位元,且 xx 为平面上的一个幅角。
多项式卷积 FFT 和 NTT

定义

将方程 zn=1z^n = 1 的所有复数根称为 nn 次单位根,这样的单位根共有 nn 个。

e2πkin(k=0,1,,n1) \large e^{\frac{2 \pi k i}{n}} \normalsize \quad(k = 0, 1, \cdots,n-1 )

这些单位根分布在复数平面的单位圆上,构成了一个正 nn 边形,它们把单位圆等分成 nn 个部分。

多项式卷积 FFT 和 NTT
简单的,定义 ω=e2πkin\omega = e^{\frac{2 \pi k i}{n}},若有 nnkk 互质,则 ω\omega 称为 nn 次本原单位根。wx(x=0,1,,n1)w^x\quad (x = 0, 1, \cdots, n-1) 构成了所有的 nn 次单位根。特殊的,当 k=1k=1 时,本原单位根记为 ωn\omega_{n}

性质

单位根的共轭复数为其倒数。

ωnk=cos2πkn+isin2πkn ωnk=ω2n2k ωnn2=eiπ=1 ωnk+n2=ωnk \omega_{n}^{k}=\cos \frac{2 \pi k}{n} +i \sin \frac{2 \pi k}{n} \\ \ \\ \omega_{n}^{k}=\omega_{2 n}^{2 k} \\ \ \\ \omega_{n}^{\frac{n}{2}}=e^{i \pi}=-1 \\ \ \\ \omega_{n}^{k+\frac{n}{2}}=-\omega_{n}^{k}

Cooley-Tukey 算法

离散傅里叶变换 DFT

多项式有两个表示方法——系数表示法和点值表示法。它们各有千秋,系数表示法适用范围广,但乘法操作为 O(n2)O(n^2);点值表示法适用范围窄,但乘法操作为线性。那么能不能在两个表示法相互转换呢?

假设现在有一个 n1n-1 次多项式,A(x)=i=0nai×xiA(x) = \sum_{i = 0}^n a_i \times x_i。为了方便,设 n=2m,mNn = 2^m, m \in \mathbb{N},不足在高位补 00

nnnn 次单位根 ωn0,ωn1,,ωnn1\omega_{n}^{0}, \omega_{n}^{1}, \ldots, \omega_{n}^{n-1} 代入 A(x)A(x) 将其转换成点值表达 A(ωnk)=i=0n1aiωkiA\left(\omega_{n}^{k}\right)=\sum_{i=0}^{n-1} a_{i} \omega^{k i}。 点值向量 y=(A(ωn0),A(ωn1),,A(ωnn1))\vec{y}=\left(A\left(\omega_{n}^{0}\right), A\left(\omega_{n}^{1}\right), \ldots, A\left(\omega_{n}^{n-1}\right)\right) 称为系数向量 a=(a0,a1,,an1)\vec{a}=\left(a_{0}, a_{1}, \ldots, a_{n-1}\right) 的离散傅里叶变换,记为 y=DFTn(a)\vec{y}= \operatorname{DFT}_{n}(\vec{a})

可以发现离散傅里叶变换的复杂度为 O(n2)O(n^2) 的。Cooley-Tukey 算法对 DFT 进行了优化,它将每一项进行了奇偶分类。当 k<n2k < \frac{n}{2}

根据性质 ωnk=ω2n2k\omega_{n}^{k}=\omega_{2 n}^{2 k}

A(ωnk)=i=0n1aiωnki=i=0n1a2iωn2ki+ωnki=0n21a2i+1ωn2ki=i=0n21a2iωn2ki+ωnki=0n21a2i+1ωn2ki A\left(\omega_{n}^{k}\right) =\sum_{i=0}^{n-1} a_{i} \omega_{n}^{k i} \\ =\sum_{i=0}^{n-1} a_{2 i} \omega_{n}^{2 k i}+\omega_{n}^{k} \sum_{i=0}^{\frac{n}{2}-1} a_{2 i+1} \omega_{n}^{2 k i} \\ = \sum_{i=0}^{\frac{n}{2}-1} a_{2 i} \omega_{\frac{n}{2}}^{k i}+\omega_{n}^{k} \sum_{i=0}^{\frac{n}{2}-1} a_{2 i+1} \omega_{\frac{n}{2}}^{k i}

根据性质 ωnk+n2=ωnk\omega_{n}^{k+\frac{n}{2}}=-\omega_{n}^{k}

A(ωnk+n2)=i=0n21a2iωn2ki+ωnk+n2i=0n21a2i+1ωn2ki=i=0n21a2iωn2kiωnki=0n21a2i+1ωn2ki \begin{aligned} A\left(\omega_{n}^{k+\frac{n}{2}}\right) &=\sum_{i=0}^{\frac{n}{2}-1} a_{2 i} \omega_{\frac{n}{2}}^{k i}+\omega_{n}^{k+\frac{n}{2}} \sum_{i=0}^{\frac{n}{2}-1} a_{2 i+1} \omega_{\frac{n}{2}}^{k i} \\ &=\sum_{i=0}^{\frac{n}{2}-1} a_{2 i} \omega_{\frac{n}{2}}^{k i}-\omega_{n}^{k} \sum_{i=0}^{\frac{n}{2}-1} a_{2 i+1} \omega_{\frac{n}{2}}^{k i} \end{aligned}

可以发现左右两个式子相似。令左式的系数表达式为 A1A_1,右式的系数表达式为 A2A_2

A(ωnk)=A1(ωn2k)+A2(ωn2k) A(ωnk+n2)=A1(ωn2k)A2(ωn2k) A\left(\omega_{n}^{k}\right) = A_1(\omega_{\frac{n}{2}}^k) + A_2(\omega_{\frac{n}{2}}^k) \\ \ \\ A\left(\omega_{n}^{k+\frac{n}{2}}\right) = A_1(\omega_{\frac{n}{2}}^k) - A_2(\omega_{\frac{n}{2}}^k)

这意味着,如果能求出 A1(ωn2k)A_1(\omega_{\frac{n}{2}}^k)A2(ωn2k)A_2(\omega_{\frac{n}{2}}^k),那么可以直接求出 A(ωnk)A\left(\omega_{n}^{k}\right)A(ωnk+n2)A\left(\omega_{n}^{k+\frac{n}{2}}\right)

于是,我们只要算出 a0,a2,,a2n2a_{0}, a_{2}, \ldots, a_{2 n-2}a1,a3,,a2n1a_{1}, a_{3}, \ldots, a_{2 n-1} 的 DFT 就可以算出 a0,a1,a2n1a_{0}, a_{1}, \ldots a_{2 n-1} 的 DFT,递归下去即可。时间复杂度 O(nlog2n)O\left(n \log _{2} n\right)

傅里叶逆变换 IDFT

刚刚计算的是 y=DFTn(a),\vec{y}=\operatorname{DFT}_{n}(\vec{a}), 可以将多项式转化成点值表示,现在为了将点值表示转化成系数表示,需要计算 IDFT,它是 DFT 的逆运算,也就是插值的过程。提起插值,可能先想起拉格朗日插值,不过 FFT 不需要它。

考虑解一个线性同余方程组

{a0(ωn0)0++an2(ωn0)n2+an1(ωn0)n1=A(ωn0)a0(ωn1)0++an2(ωn1)n2+an1(ωn1)n1=A(ωn1)a0(ωnn1)0++an2(ωnn1)n2+an1(ωnn1)n1=A(ωnn1) \left\{\begin{array}{ccccc} a_{0}\left(\omega_{n}^{0}\right)^{0} & +\cdots & +a_{n-2}\left(\omega_{n}^{0}\right)^{n-2} & +a_{n-1}\left(\omega_{n}^{0}\right)^{n-1} & =A\left(\omega_{n}^{0}\right) \\ a_{0}\left(\omega_{n}^{1}\right)^{0} & +\cdots & +a_{n-2}\left(\omega_{n}^{1}\right)^{n-2} & +a_{n-1}\left(\omega_{n}^{1}\right)^{n-1} & =A\left(\omega_{n}^{1}\right) \\ \vdots & \vdots & \vdots & \vdots \\ a_{0}\left(\omega_{n}^{n-1}\right)^{0} & +\cdots & +a_{n-2}\left(\omega_{n}^{n-1}\right)^{n-2} & +a_{n-1}\left(\omega_{n}^{n-1}\right)^{n-1} & =A\left(\omega_{n}^{n-1}\right) \end{array}\right.

写成矩阵的形式

[(ωn0)0(ωn0)1(ωn0)n1(ωn1)0(ωn1)1(ωn1)n1(ωnn1)0(ωnn1)1(ωnn1)n1][a0a1an1]=[A(ωn0)A(ωn1)A(ωnn1)] \left[\begin{array}{cccc} \left(\omega_{n}^{0}\right)^{0} & \left(\omega_{n}^{0}\right)^{1} & \cdots & \left(\omega_{n}^{0}\right)^{n-1} \\ \left(\omega_{n}^{1}\right)^{0} & \left(\omega_{n}^{1}\right)^{1} & \cdots & \left(\omega_{n}^{1}\right)^{n-1} \\ \vdots & \vdots & \ddots & \vdots \\ \left(\omega_{n}^{n-1}\right)^{0} & \left(\omega_{n}^{n-1}\right)^{1} & \cdots & \left(\omega_{n}^{n-1}\right)^{n-1} \end{array}\right]\left[\begin{array}{c} a_{0} \\ a_{1} \\ \vdots \\ a_{n-1} \end{array}\right]=\left[\begin{array}{c} A\left(\omega_{n}^{0}\right) \\ A\left(\omega_{n}^{1}\right) \\ \vdots \\ A\left(\omega_{n}^{n-1}\right) \end{array}\right]

左矩阵即为系数矩阵 VV,要求它的逆矩阵 V1V^{-1}。可以发现,这个矩阵可以使用范德蒙德矩阵的逆矩阵公式,令 DDVV 的伴随矩阵。

V1=1nD=1n[(ωn0)0(ωn0)1(ωn0)n1(ωn1)0(ωn1)1(ωn1)n1(ωn(n1))0(ωn(n1))1(ωn(n1))n1] {V}^{-1}=\frac{1}{n} {D}=\frac{1}{n}\left[\begin{array}{cccc} \left(\omega_{n}^{-0}\right)^{0} & \left(\omega_{n}^{-0}\right)^{1} & \cdots & \left(\omega_{n}^{-0}\right)^{n-1} \\ \left(\omega_{n}^{-1}\right)^{0} & \left(\omega_{n}^{-1}\right)^{1} & \cdots & \left(\omega_{n}^{-1}\right)^{n-1} \\ \vdots & \vdots & \ddots & \vdots \\ \left(\omega_{n}^{-(n-1)}\right)^{0} & \left(\omega_{n}^{-(n-1)}\right)^{1} & \cdots & \left(\omega_{n}^{-(n-1)}\right)^{n-1} \end{array}\right]

证明较为复杂,我们简单验证一下,设 E=V×DE = V \times D,则有

Ei,j=k=0n1DikVkj=k=0n1ωnikωnkj=k=0n1ωnk(ji) E_{i, j}=\sum_{k=0}^{n-1} D_{i k} V_{k j}=\sum_{k=0}^{n-1} \omega_{n}^{-i k} \omega_{n}^{k j}=\sum_{k=0}^{n-1} \omega_{n}^{k(j-i)}

i=ji=j 时,显然 Ei,j=nE_{i,j}=n。当 iji \neq j 时,有

Ei,j=k=0n1(ωnji)k=1(ωnji)n1ωnji=0 E_{i, j}=\sum_{k=0}^{n-1}\left(\omega_{n}^{j-i}\right)^{k}=\frac{1-\left(\omega_{n}^{j-i}\right)^{n}}{1-\omega_{n}^{j-i}}=0

因此 DD 的主对角线都是 nn,其它位置都是 00,除以 nn 后即为单位矩阵,证毕

综上所述,可以得到

[a0a1an1]=1n[(ωn0)0(ωn0)1(ωn0)n1(ωn1)0(ωn1)1(ωn1)n1(n1)(ωn(n1))1(ωn(n1))n1][A(ωn0)A(ωn1)A(ωnn1)] \left[\begin{array}{c} a_{0} \\ a_{1} \\ \vdots \\ a_{n-1} \end{array}\right]=\frac{1}{n}\left[\begin{array}{cccc} \left(\omega_{n}^{-0}\right)^{0} & \left(\omega_{n}^{-0}\right)^{1} & \cdots & \left(\omega_{n}^{-0}\right)^{n-1} \\ \left(\omega_{n}^{-1}\right)^{0} & \left(\omega_{n}^{-1}\right)^{1} & \cdots & \left(\omega_{n}^{-1}\right)^{n-1} \\ \vdots & \vdots & \ddots & \vdots \\ -(n-1) & \left(\omega_{n}^{-(n-1)}\right)^{1} & \cdots & \left(\omega_{n}^{-(n-1)}\right)^{n-1} \end{array}\right]\left[\begin{array}{c} A\left(\omega_{n}^{0}\right) \\ A\left(\omega_{n}^{1}\right) \\ \vdots \\ A\left(\omega_{n}^{n-1}\right) \end{array}\right]

IDFT 就相当于把 DFT 过程中的 wniw_n^i 换成 wniw_n^{-i},然后做一次 DFT,将结果除以 nn 即可。

递归实现

迭代实现

NTT

原根