fft&ntt
FFT:
单位根:
在复平面上,以原点为圆心,$1$为半径作圆,所得的圆叫单位圆。以圆点为起点,圆的$n$等分点为终点,做$n$个向量,设幅角为正且最小的向量对应的复数为
$\omega_n$,称为$n$次单位根。
单位根计算公式:$\omega_{n}^{k}=cos \frac{k \times 2 \pi}{n} + i sin\frac{k \times 2 \pi}{n}$
单位根性质:
1.$\omega_{n}^{x+y}=\omega_{n}^{x} \times \omega{n}^{y}$
证明方法:由复数的乘法运算方法为幅角相加,模长及单位根的定义可得
2.$\omega_{n}^{k}=\omega_{2n}^{2k}$
直接由公式证明即可:$cos \frac{k \times 2 \pi}{n} + i sin\frac{k \times 2 \pi}{n}=cos \frac{2k \times 2 \pi}{2n} + i sin\frac{2k \times 2 \pi}{n}$
3.$\omega_{n}^{k}=- \omega_{n}^{k+ \frac{n}{2}}$
证明方法:$\omega_{n}^{\frac{n}{2}}=cos \frac{\frac{n}{2} \times 2 \pi}{n} + i sin\frac{\frac{n}{2} \times 2 \pi}{n}=cos \pi + sin \pi =-1$
4.$\omega_{n}^{k}=\omega_{n}^{k+n}$
证明方法:公式
5.$\omega_{n}^{0}=\omega_{n}^{n}=1$
快速傅里叶变换
由此可见,我们只需要计算$\omega_{n}{k} (k \in [0,\frac{n}{2}-1])$ 就可以了
容易发现这样计算序列${a_0,a_1,\dots ,a_{n-1}}$只需要下传$log n$ 层
时间复杂度O(n log n)
快速傅里叶逆变换
既然系数表示法能转成点值表示法,那么我们不妨将点值表示法的序列${y_0,y_1,y_2,\dots,y_{n-1}}$当成系数表示法
然后设序列c为以序列y为系数表示法得到的点值表示法,看看序列c和实际的系数表示法直接的联系
$c_k= \sum y_i * (\omega_n^{-k})^i $
$=\sum_{i=0}^{n-1} \sum_{j=0}^{n-1} a_j*(\omega_n^i)^j * (\omega_n^i)^k$
$=\sum_{j=0}^{n-1} a_j* \sum_{i=0}^{n-1} (\omega_n^{i})^{j-k}$
由性质3可知,当$j-k != 0$ 时,$\sum_{i=0}^{n-1} (\omega_n^{i})^{j-k}=0$
所以$c_k=a_k * n$
理论部分就到此结束了qwq
代码实现
像这样正着传会进行很多的重复操作
所以我们要倒着传才能达到$O(n log n)$
倒着传的流程图如下
打表发现,最后一层的数值为a[下标二进制反转]
fft完结撒花
NTT:
快速数论变换,可以取模(但只能处理系数为整数的多项式运算)
原根:
Definition:对于$g,p \in Z$,如果$g^i \space mod \space p,(i \in [1,p-1])$的值互不相同,那么称g为p的原根
Instance: $998244353,1004535809,469762049的原根都是3$
性质
我们将$g^{(p-1)/n}当做原根中的\omega_{n}^{1}$
性质1:指数乘法运算法则
性质2:指数乘法运算法则
性质3:由于$(g^{k*(p-1)/n})^2=(g^{k*(p-1)/n+(p-1)/2})^2,根据原根的性质可知g^{k*(p-1)/n}!=g^{k*(p-1)/n+(p-1)/2}$,所以这两个东西是相反数
性质4:费马小定理
性质5:费马小定理
过程&代码实现同fft
ntt完结撒花