fft
\[\large\large\large{\text{快速傅里叶变换}}
\]
\[\;\;\;\;\;\;\;\;\;\;\;\;\;\;By\;tyq
\]
介绍
这个算法干什么?——快速的计算多项式乘法
这个算法时间复杂度是多少——O(NlogN)
怎么搞?
一些定义
\[\text{多项式}\;A(x) = \sum_{i=1}^{N}a_ix^i
\]
\[\text{多项式A和B的乘积C}\;C(x) = \sum_{i=1}^{2 \times N}c_i \times x^i
\]
\[其中c_k=\sum_{i+j=i,0 \leq i,j < n}a_i \times b_j \times x^k
\]
\[\text{(虚数单位)} i = \sqrt{-1}
\]
\[\text{N次单位根}\omega_n^j = e^{\frac{2ij\pi}{n}}=(\omega_n)^j
\]
\[w_n=e^{\frac{2i\pi}{n}}{}
\]
接下来说在怎么fft
引理
\[(\omega_n^i)^2\text{所构成的集合}=\omega_{\frac{n}{2}}^i
\]
\[\text{证明:}\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;
\]
\[\text{带入定义易证}
\]
坑以后填
#include<complex>
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std ;
#define complexs complex<double>
#define N 2621450
const double Pi = acos(-1) ;
int limit = 1 ;
int r[N] ;
void fft(complexs* A, int type) {
for (int i = 0; i < limit; i++)
if (i < r[i]) swap(A[i], A[r[i]]);
for (int mid = 1; mid < limit; mid <<= 1) {
complexs Wn( cos(Pi / mid) , type * sin(Pi / mid) );
for (int R = mid << 1, j = 0; j <limit; j += R) {
complexs w(1, 0);
for (int k = 0; k < mid; k++, w = w * Wn) {
complexs x = A[j + k], y = w * A[j + mid + k];
A[j + k] = x + y;
A[j + mid + k] = x - y;
}
}
}
}
complexs A[N],B[N] ;
int main(){
int n,m,l=0 ; scanf("%d%d",&n,&m) ;
for(limit=1;limit<=n+m;limit<<=1) ++l;
for (int i = 0; i < limit; i++)
r[i]=(r[i>>1]>>1)|((i&1)<<(l-1)) ;
int x ;
for(int i=0;i<=n;++i) {scanf("%d",&x) ; A[i]=complexs(x,0) ;}
for(int i=0;i<=m;++i) {scanf("%d",&x) ; B[i]=complexs(x,0) ;}
fft(A,1) ; fft(B,1) ;
for(int i=0;i<limit;++i) A[i] = A[i]*B[i] ;
fft(A,-1) ;
for(int i=0;i<=n+m;++i){
printf("%d ",int(A[i].real()/limit+0.5)) ;
}
puts("") ;
return 0 ;
}