快速傅里叶变换用于加速多项式的乘法,复杂度O(nlogn),例题:http://uoj.ac/problem/34
详解:https://www.cnblogs.com/RabbitHu/p/FFT.html
模板:
#include<bits/stdc++.h> #define PI acos(-1.0) using namespace std; struct Complex{ double real,img; Complex(const double &real=0.0,const double &img=0.0):real(real),img(img){} Complex operator + (const Complex &c) const {return Complex(real+c.real,img+c.img); } Complex operator - (const Complex &c) const {return Complex(real-c.real,img-c.img); } Complex operator * (const Complex &c) const {return Complex(real*c.real-img*c.img,real*c.img+img*c.real); } }a[100005*4],b[100005*4],omg[100005*4],inv[100005*4];//长度为fn的大小 void init(int n){ for(int i = 0; i < n; i++){ omg[i] = Complex(cos(2 * PI * i / n), sin(2 * PI * i / n)); inv[i] = Complex(cos(2 * PI * i / n), -1.0*sin(2.0 * PI * i / n)); } } void fft(Complex *a,int n,Complex *omg){ int lim = 0; while((1 << lim) < n) lim++; for(int i = 0; i < n; i++){ int t = 0; for(int j = 0; j < lim; j++) if((i >> j) & 1) t |= (1 << (lim - j - 1)); if(i < t) swap(a[i], a[t]); } for(int l = 2; l <= n; l *= 2){ int m = l / 2; for(Complex *p = a; p != a + n; p += l) for(int i = 0; i < m; i++){ Complex t = omg[n / l * i] * p[i + m]; p[i + m] = p[i] - t; p[i] = p[i] + t; } } } int main() { int n,m;scanf("%d%d",&n,&m); for(int i=0;i<=n;i++) scanf("%lf",&a[i].real); for(int i=0;i<=m;i++) scanf("%lf",&b[i].real); int fn=1;//fn-1次多项式,fn=2^k while(fn<=n+m) fn<<=1; init(fn); fft(a,fn,omg); fft(b,fn,omg); for(int i=0;i<fn;i++) a[i]=a[i]*b[i]; fft(a,fn,inv); for(int i=0;i<=n+m;i++) printf("%d ",int(a[i].real/fn+0.5)); puts(""); return 0; }