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
]