Orz myy!
特殊模数
如果模数很特殊,
(2k+1)|(p−1),
(p−1)>DFT的长度,那么可以求出p的原根g,用
g代替单位复数根
wn。
不会原根?
请点这里
一般模数
那就不能用
原根代替单位复数根这种方法了。
只能用实数。
但是如果模数很大,比如
1000000007,用double的话很可能爆精度。
目标:解决精度问题。
1.用中国剩余定理:
对每个模数分别做3次DFT。一般998244353 , 1004535809 ,9985661441
然后将三次的计算结果乘起来,对要求的模数取模即可。
可行条件:三个模数的乘积大于
np2
优点:降低错误率。
缺点:做
9次DFT,太慢了。常数巨大。
2.
7遍DFT
将两个多项式拆一下:
Ai=ai∗P−−√+bi,
Bi=ci∗P−−√+di
通过乘法分配律,则
Ai∗Bi=P∗(ai∗ci)+P−−√(ai∗di+bi∗ci)+bi∗di
看得出来,做4次点值,分别求出
ai∗ci,bi∗di,ai∗di,bi∗ci
再做3次插值,分别对三种颜 {MOD}部分求插值即可。
然而还不优。
重头戏
myy的算法中(DFT+IDFT)的次数只有4次。
看看这究竟是什么奇技淫巧吧。
一个多项式的系数表示是这样的:
A(x)=Σn−1i=0aixi
在做DFT的时候,
ai的虚部一开始都为0。很多人以为这没用。实际上并不然。
这个算法巧妙地利用了虚部的空间。
如果
ai=ki+i∗bi,又会怎么样?
考虑1次DFT搞定原来2次DFT得出的多项式A,B.
凑式子
问题来了,现在既要考虑充分利用虚部空间,又要考虑凑式子。
设
C(x)=Σn−1i=0aix