FFT

FFT

用来解决多项式相乘问题。

算法流程:

将两个多项式转为点值表达-->点值表达相乘搞出答案多项式的点值表达-->将答案的点值表达变为系数表达-->输出。

其中将系数表达变为点值表达的算法叫做 dft

对于一个(n)多项式(F(x)),我们需要求出(F'(x)=F(omega_n^x))。(点值表达)

这个过程我们可以分治求解,理论依据是以下两个公式:

[color{blue}{F(omega_n^k)=Fl(omega_{n/2}^k)+omega_n^kFr(omega_{n/2}^k)\ F(omega_n^{k+n/2})=Fl(omega_{n/2}^k)-omega_n^kFr(omega_{n/2}^k)} ]

证明(1):

[F(omega_n^k)=Fl((omega_{n/2}^k)^2)+omega_{n/2}^k imes Fr((omega_{n/2}^k)^2) \ =Fl(omega_n^{2k})+omega_{n/2}^k imes Fr(omega_n^{2k})\=Fl(omega_{n/2}^k)+omega_n^kFr(omega_{n/2}^k) ]

证明(2):

[ F(omega_n^{k+n/2})=Fl((omega_n^{k+n/2})^2)+omega_n^{k+n/2} imes Fr((omega_n^{k+n/2})^2)\ ]

(omega_n^{k+n/2}=omega_n^k imesomega_n^{n/2}=-omega_n^k)

[ =Fl(omega_{n}^{2k+n})-omega_n^k imes Fr(omega_{n}^{2k+n}) ]

(omega_n^{kmod n}=w_n^k)

[= Fl(omega_{n/2}^k)-omega_n^kFr(omega_{n/2}^k) ]

所以要求出一个多项式的点值表达,我们可以分治(Theta (n log n))解决。

设点值为(G),系数为(F)

根据点值代入的原理,我们可以知道:

[G_k=sum_{i=1}^n(omega_n^k)^i imes F_i ]

通过这个式子,我们可以将(G)反推回(F)

先说结论:

[color{blue}n imes F[k] = sum_{i=1}^{n}(omega_n^{-k})^i imes G_i ]

证明:代入得:

[sum_{i=1}^{n}(omega_n^{-k})^i imes G_i=sum_{j=1}^n(omega_n^{-k})^jsum_{i=1}^n(omega_n^j imes F_i) ]


FFT 实际上是优化卷积的一种方法,

卷积 :

[C_k=sum_{i=1}^nA_i imes B_{k-i} ]

容易发现两个多项式相乘实际上就是卷积的一种形式。

题目: ZJOI2014力

给出 (n) 个数,(q_i),给出(F_j)的定义如下:

[ F_j=sum_{i<j}dfrac{qi imes qj}{(i-j)^2}-sum _{i>j} dfrac{qi imes qj}{(i-j)^2} ]

(E_i=dfrac{F_i}{q_i}),求(E_i)

显然

[ E_j=sum_{i=1}^{j-1}dfrac{qi}{(i-j)^2}-sum_{i=j+1}^{n} dfrac{q_i}{(i-j)^2} ]


(这时我参考了一下题解)

(g_i=dfrac{1}{i^2}),原式化为,我们再定义(dfrac{1}{0}=0)

[ E_j=sum_{i=1}^{j} qi imes g_{j-i} - sum _{i=j}^{n} q_i imes g_{j-i} ]

我们惊喜的发现左边已经变成了卷积的形式!

有一个想法就是我们可以分别计算两边的卷积,最后再加上。

右边的式子我们可以套路解决:

[ sum_{i=j}^n q_i imes g_{(i-j)} \ 在g那里加上j,再将 sum 转化为关于g的表述:\ sum_{i=1}^{n-j}=q_{i+j} imes g_i ]

继续使用套路,设(q'_i=q_{n-i})

[ sum_{i=1}^{n-j}q_{i+j} imes g_i \ =sum_{i=1}^{n-j}q'_{n-(n-(i+j))} imes g_i ]

还有一个套路: 设(t=n-j):

[ sum_{i=1}^{t}q'_{(n-(i+j))} imes g_i \ = sum_{i=1}^{t}q'_{(n-i-j)} imes g_i \ = sum_{i=1}^{t}q'_{(t-i)} imes g_i \ ]

又是一个卷积!这样我们就可以进行fft了!

总结一下:

  • 我们需要两个数组: (q'_i=q_{n-i})(g_x=dfrac{1}{x^2})
  • 然后我们要进行两次fft,然后再相减:

[ Left_j=sum_{i=1}^{j} qi imes g_{j-i} \ Right_t=sum_{i=1}^{t}q'_{(t-i)} imes g_i ]

原文地址:https://www.cnblogs.com/guodongLovesOi/p/12268763.html