FFT:
单位根:
在复平面上,以原点为圆心,$1$为半径作圆,所得的圆叫单位圆。以圆点为起点,圆的$n$等分点为终点,做$n$个向量,设幅角为正且最小的向量对应的复数为
$omega_n$,称为$n$次单位根。
单位根计算公式:$omega_{n}^{k}=cos frac{k imes 2 pi}{n} + i sinfrac{k imes 2 pi}{n}$
单位根性质:
1.$omega_{n}^{x+y}=omega_{n}^{x} imes omega{n}^{y}$
证明方法:由复数的乘法运算方法为幅角相加,模长及单位根的定义可得
2.$omega_{n}^{k}=omega_{2n}^{2k}$
直接由公式证明即可:$cos frac{k imes 2 pi}{n} + i sinfrac{k imes 2 pi}{n}=cos frac{2k imes 2 pi}{2n} + i sinfrac{2k imes 2 pi}{n}$
3.$omega_{n}^{k}=- omega_{n}^{k+ frac{n}{2}}$
证明方法:$omega_{n}^{frac{n}{2}}=cos frac{frac{n}{2} imes 2 pi}{n} + i sinfrac{frac{n}{2} imes 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完结撒花