Bluestein's Algorithm
Bluestein's Algorithm 用于当不是 \(2\) 的整数次幂时对多项式的 (I)DFT。
考虑现在要求:
Bluestein 的核心思想在于拆 \(mk\)。不难证明 \(mk = \frac{m(m - 1)}{2} + \frac{k(k + 1)}{2} - \frac{(m - k)(m - k - 1)}{2}\)。那么:
这样我们把这个东西化成了卷积形式。但是发现 \(m - k\) 可能是负数,所以需要把另外一个多项式平移 \(n\) 位再做卷积。
时间复杂度是 \(O((n + m) \log n)\)。
注意到我们没有用到 \(w\) 是模意义下的单位根的特性,所以这里 \(w\) 其实可以取任意整数,所以 Bluestein's Algorithm 其实就是代入一个等比数列,然后多点求值。
注意有些博客说的 \(mk = \frac{1}{2} (m^2 + k^2 - (m - k)^2)\) 有局限性,因为 \(w\) 可能没有二次剩余。
1. P6800 【模板】Chirp Z-Transform & P6828 任意模数 Chirp Z-Transform
模板。
2. HDU4656 Evaluation
Bluestein 不是正解,因为内存很卡。
可以一次性把 \(f(1), f(2), \ldots, f(P - 1)\) 都算出来。找 \(P\) 的原根 \(g\),变成算 \(f(g^0), f(g^1), \ldots, f(g^{P - 2})\)。
套任意模的模板即可。
3. P5293 [HNOI2019] 白兔之舞
所求即为:
接下来是一个 IDFT 的模板,直接套 Bluestein's Algorithm 即可。
4. P4191 [CTSC2010] 性能优化
循环卷积相当于直接 DFT 然后点乘起来再 IDFT 回去。
所以做 \(k\) 次循环卷积相当于每个点变成它的 \(k\) 次方。
至于如何 DFT,当然可以使用 Bluestein's Algorithm。但是也可以考虑类似 FFT 的方法,每次找到 \(n\) 的最小质因子 \(p\),设 \(F_k(x) = \sum\limits_{i = 0}^{\frac{n}{p} - 1} a_{ip + k} x^i\),那么有 \(F(x) = \sum\limits_{i = 0}^{p - 1} x^i F_i(x)\),即 \(F(\omega_n^i) = \sum\limits_{j = 0}^{p - 1} \omega_n^{ij} F_j(\omega_{\frac{n}{p}}^{i \bmod \frac{n}{p}})\)。合并上去即可。
5. POJ2821 TN's Kingdom III - Assassination
循环卷积,直接 DFT 后除过去再 IDFT 即可。

浙公网安备 33010602011771号