一、 NTT的局限
对于模数符合下列条件的多项式乘法,我们可以用NTT。
- 模数为 P = r ∗ 2 k + 1 P=r*2^k+1 P=r∗2k+1, 其中 k k k足够大,满足 2 k > = N 2^k>=N 2k>=N, N N N为多项式扩充后的项数。因为多项式乘法都需要将项数扩充到 2 2 2的幂。
而如果不满足这个条件,则我们无法使用 N T T NTT NTT直接做了。
而要使用 F F T FFT FFT解决带模的多项式乘法,则要保证在不考虑模数的情况下,多项式乘积的系数不能超过 d o u b l e double double能表示的精度。一般 d o u b l e double double的精度在 1 0 16 10^{16} 1016,所以如果系数超过 1 0 16 10^{16} 1016以后,则用double不能精确表示了。
二、 任意模数的多项式乘法
模数为任意整数时的多项式乘法该如何解决呢?
1. 三模数NTT
有两种解决思路,第一种是三模数 N T T NTT NTT。即找三个模数,这三个模数都需满足上述 N T T NTT NTT的条件。分别求出在三个模数下的多项式乘法的结果,然后再利用中国剩余定理,求出在给定模数下的结果。
设给定的模数为 m o d mod mod, 自己找的三个模数为 m o d 1 , m o d 2 , m o d 3 mod1,mod2,mod3 mod1,mod2,mod3,这三个模数除了要满足上述 N T T NTT NTT的条件外,还需要满足:
m o d 1 × m o d 2 × m o d 3 mod1\times mod2 \times mod3 mod1×mod2×mod3大于结果多项式中的所有系数,其中两个 m o d mod mod的乘积要在long long 范围以内。
对多项式结果的系数 c c c:有:
{ c ≡ c 1 ( m o d m o d 1 ) c ≡ c 2 ( m o d m o d 2 ) c ≡ c 3 ( m o d m o d 3 ) \begin{aligned} \begin{cases} c \equiv c_1 \pmod {mod1} \\ c \equiv c_2 \pmod {mod2} \\ c \equiv c_3 \pmod{mod3} \end{cases} \end{aligned} ⎩ ⎨ ⎧c≡c1(modmod1)c≡c2(modmod2)c≡c3(modmod3)
根据扩展中国剩余定理,由前两个方程可知:
c 1 + m o d 1 × k 1 = c 2 + m o d 2 × k 2 c1+mod_1 \times k_1 = c2+ mod_2 \times k_2 c1+mod1×k1=c2+mod2×k2
k 1 × m o d 1 ≡ ( c 2 − c 1 ) ( m o d m o d 2 ) k_1 \times mod_1 \equiv (c2-c1) \pmod{mod_2} k1×mod1≡(c2−c1)(modmod2)
k 1 = ( c 2 − c 1 ) × m o d 1 − 1 ( m o d m o d 2 ) k_1 = (c_2-c_1) \times mod_1^{-1} \pmod{mod_2} k1=(c2−c1)×mod1−1(modmod2)
求出了 k 1 k_1 k1以后,就可以求出来前两个方程下的 c c c的值:
c ≡ ( c 2 − c 1 ) × m o d 1 − 1 × m o d 1 + c 1 ( m o d m o d 1 × m o d 2 ) (2) c \equiv (c_2-c_1) \times mod_1^{-1} \times mod_1+c_1 \pmod{mod_1 \times mod_2} \tag {2} c≡(c2−c1)×mod1−1×mod1+c1(modmod1×mod2)(2)
观察上式,发现有 m o d 1 − 1 × m o d 1 mod_1^{-1} \times mod_1 mod1−1×mod1,这不就是 1 1 1吗?
那 2 2 2式不变成了 c ≡ c 2 c \equiv c2 c≡c2了吗?
不是的,这里要注意,上面的式子中 m o d 1 − 1 mod_1^{-1} mod1−1是指在模 m o d 2 mod_2 mod2意义下 m o d 1 mod_1 mod1的逆元,而在模 m o d 1 × m o d 2 mod_1 \times mod_2 mod1×mod2意义下, m o d 1 − 1 × m o d 1 mod_1^{-1} \times mod_1 mod1−1×mod1就不是逆元了,其不一定为 1 1 1.
举个例子: m o d 1 mod_1 mod1为 5 5 5, m o d 2 mod_2 mod2为 7 7 7, 在 m o d 2 mod_2 mod2意义下, m o d 1 − 1 mod_1^{-1} mod1−1为 3 3 3, 在 m o d 1 × m o d 2 mod_1\times mod_2 mod1×mod2意义下, 5 × 3 5 \times 3 5×3并不等于 1 1 1.
然后将该式与方程组中的第三个方程联立起来,设 m = ( c 2 − c 1 ) × m o d 1 − 1 × m o d 1 + c 1 m=(c_2-c_1) \times mod_1^{-1} \times mod_1+c_1 m=(c2−c1)×mod1−1×mod1+c1,
可以得到:
c ≡ ( c 3 − m ) × ( m o d 1 × m o d 2 ) − 1 × ( m o d 1 × m o d 2 ) + m ( m o d m o d 1 × m o d 2 × m o d 3 ) c \equiv (c_3-m) \times (mod_1 \times mod_2)^{-1} \times (mod_1 \times mod_2) + m \pmod{mod_1\times mod_2 \times mod_3} c≡(c3−m)×(mod1×mod2)−1×(mod1