如何使用FFT算法计算N个给定特定点的N次多项式值

时间:2018-04-16 10:39:24

标签: algorithm

这基本上是我在波兰的奥林匹克运动会上给出的任务,现在已经结束了。值应为模M(给定)。它现在,我知道我需要使用FFT算法来解决它在O(Nlog(N))复杂性。

  1. N是2的幂(N <= 2 ^ 20)并且(q ^ N mod M)= 1;
  2. 值是给定的(q)的1到N的幂。例如 当q = 5且N = 3时,输出应包含:F(q ^ 1 mod M),F(q ^ 2 mod M),F(q ^ 3 mod M)。
  3. a1,a2 ... aN在输入中给出(多项式中的常数)
  4. 野蛮力量是N ^ 2,那太慢了。我认为radix-2算法非常合适,但是我不知道它会如何在FFT中使用复数来提供解决方案。

1 个答案:

答案 0 :(得分:1)

您将使用的算法与FFT几乎相同,但您使用的是残差mod M而不是复数。如果您添加 M 为素数且所有 q ^ i 为不同的mod M 的其他约束,那么您将拥有数论变换:

https://www.nayuki.io/page/number-theoretic-transform-integer-dft

但是你并不需要那些额外的限制来解决你的问题。

首先,因为基于1的索引很烦人,所以我会将你的 a [N] 称为 a [0] ,而我是我将把您的 N 输出移动到索引 0 的开头,因为它使下面的讨论变得更加容易。

所以你想要:

out [0] = a [0] + a [1] + a [2] ... a [i] ... a [N-1]

out [1] = a [0] + a [1] * q + a [2] * q ^ 2 ... a [i] * q ^ i ... a [N-1 ] * q ^(N-1)

<强> ...

out [j] = ... + a [i] * q ^(ij)...

请注意,如果你有任何 out [j] 的公式,你可以通过乘以系数来制作 out [j] +1 的公式a [...] by 1,q,q ^ 2,... 因此,如果我们有办法计算偶数输出,我们可以将它应用于修改后的那些用于计算奇数输出的系数。

现在,对于偶数输出, q 的所有幂都是 q ^ 2 的幂,并且它们重复,因为 q ^ N = q ^ 0 mod M 。因此,对于偶数编号的输出,而不是计算:

out [j] = a [0] + a [1] * q ^ j + ... + a [N-1] * q ^(j(N-1))... < /强>

我们可以用一半的系数计算它,如:

out [j] =(a [0] + a [N / 2])+ ... +(a [i] + a [N / 2 + i])^(q ^ 2) ^(ij / 2)......

只是使用 q * 2 N / 2 代替 q N

所以,就像(FFT的时间版本中的抽取)一样,你可以通过将 a [...] 转换为两个新的系数集来解决你的问题,每个系数的大小只有一半,然后使用这些系数分别用 q ^ 2 M / 2 两次解决较小的问题,分别生成偶数和奇数输出。

我希望有帮助...我知道很难遵循,但如果您已经了解FFT的工作原理,那么您现在可以看到如何将其应用于您的问题。