其求解只需要nlogn就可以了.具体的解法随便一本关于傅里叶变换的书都会有介绍.
题外话:FFT还有一个特性就是变换后,频域和时域相互映射起来,这个在工程某些方面这个特性是很有用的.比如滤波,信号处理,数据压缩等等多个方面.有很大的作用(其他如余弦变换,小波变换也有类似的功能,但在有限域内这个特性一般都没有了),在高精度计算里,这个特性并没有用上.略过不表.
FNT,一般指代的是快速数论变换(也有人指FNT是指快速数论变换里面的费马变换,但是由于费马素数太少,实际的应用只存在特定领域),
这里基于代码简单化起见,特指是基2的快速数论变换,但要说明的是,FNT不仅仅包含基2的快速数论变换.
FNT实际只是FFT在有限域的一种表现形式.类比说就是FFT其插值是取复数域内的N次方根,FNT其插值是取某个剩余系内的N次方根.其余的运算和FFT基本一致.
FNT额外的好处就是由于在有限域下计算,只要数据不产生溢出,里面的精度是不会丢失的.这个要比FFT要好.
FNT里面的相关参数主要有M,N,α(或记作r),M为模,N为变换长度,α(r)为N次方根(MOD M下),只要选取的M存在N次方根,这个选取M就是可用的.就这点来说,这个选取还是比较宽松的,如果还需要考虑计算的效率问题(主要是a * b % M这个过程),选取的M则需要好好考虑.
选择M基于下面一些考虑.
变换长度为N,则必须存在N次方根(这个是FNT的内在要求)
高精度计算里,卷积的结果范围为N * (R - 1)^2,则必须M > N * (R - 1)^2 (R为进制)
计算尽可能简单.(这个是高精度要求,也可以算是卷积要求)
附:计算尽可能简单不等于尽可能小.比如M = 2^32 ±1 这个的计算就都比M = 123456789要简单.(实际运行效率要求)
显然,这里没有要求M必须是素数.这就留出了较大的优化空间.