这基本上是我在波兰的奥林匹克运动会上给出的任务,现在已经结束了。值应为模M(给定)。它现在,我知道我需要使用FFT算法来解决它在O(Nlog(N))复杂性。
野蛮力量是N ^ 2,那太慢了。我认为radix-2算法非常合适,但是我不知道它会如何在FFT中使用复数来提供解决方案。
答案 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的工作原理,那么您现在可以看到如何将其应用于您的问题。