Loading

Loading

FFT&NTT&FWT

高二了还不会 \(FFT\) ?
\(Fast Fourier Transform(FFT)\) 在 oi 中的主要作用是用来求“卷积”(多项式乘法)。
可将时间复杂度降为 \(O(n \log_2n)\)

3步快速求出多项式乘积:

  1. 由系数表示法转换成点值表示法。
  2. 求两个多项式的乘积。
  3. 将点值表示法转换成系数表示法。

假设A的点值表达式为\({(x_0,y_0),(x_1,y_1),(x_2,y_2)...}\)
假设B的点值表达式为\({(x_0,y_0^1),(x_1,y_1^1),(x_2,y_2^1)...}\)
那么C的点值表达式为\({(x_0,y_0y_0^1),(x_1,y_1y_1^1),(x_2,y_2y_2^1)...}\)

接下来分析1.
将一个 \(n\) 次项的多项式分成奇函数,偶函数两个部分。
image

接下来考虑如何选点获得点值。
对于一个奇函数,求出一组 \((x,y)\) 的值,同时可得到 \((-x,-y)\)
对于一个偶函数,求出一组 \((x,y)\) 的值,同时可得到 \((-x,y)\)
所以我们可以通过函数的性质,求出一个点的坐标就能得到两个点的坐标。一个 \(d\) 阶的多项式需要 \(d+1\) 个点,所以只需要求 \(d/2\) 次点即可。

将原多项式转化为两个子问题递归求解,于是时间复杂度降到 \(log\) 级别。

但是,真的如此吗?
注意到对于每个求值点对应的坐标都为平方数,所以都是正的,上述关于正负推出的递归显然不成立。
有点伤心。
那找到平方为负数的数是不是问题就解决了?

好。复数上场。

考虑复数的三角恒等变换。开始推。
\(n\) 次单位复数根是满足 $ \omega^n=1$ 的复数 \(\omega\)
注意到 \(k\) 阶单位复数根即为\(\omega_k^1\)
由折半定理,得到:如果 \(n\) 是大于 0 的偶数,那么 \(n\)\(n\) 个单位复数根的平方的集合就是 \(n/2\)\(n/2\) 个单位复数根的平方的集合。
注意到,由折半定理我们发现前半部分的值和后半部分的值相同,这样问题就被分成两个子问题,再对这两个子问题进行递归求解即可。
这样2.完成。
那么对于3.就很简单,通过矩阵乘法,将点值转化为系数只需要将点值表达式再做一遍FFT,最后每项除以长度即可。

posted @ 2023-10-24 22:05  Miya555  阅读(88)  评论(0)    收藏  举报