UOJ #34 多项式乘法 FFT快速傅立叶变换

题目大意:这是一道模板题。

CODE:

#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAX 1000010using namespace std;const double PI = acos(-1.0);struct Complex{double x,y;Complex(double _,double __ = .0):x(_),y(__) {}Complex() {}void operator +=(const Complex &a) {x += a.x,y += a.y;}void operator -=(const Complex &a) {x -= a.x,y -= a.y;}void operator /=(double a) {x /= a,y /= a;}void operator *=(const Complex &a) {double _ = x * a.x – y * a.y,__ = x * a.y + y * a.x;x = _,y = __;}Complex operator +(const Complex &a)const {return Complex(x + a.x,y + a.y);}Complex operator -(const Complex &a)const {return Complex(x – a.x,y – a.y);}Complex operator /(double a)const {return Complex(x / a,y / a);}Complex operator *(const Complex &a)const {return Complex(x * a.x – y * a.y,x * a.y + y * a.x);}};inline void FFT(Complex A[],int cnt,int flag) {for(int i = 0,k = 0; i < cnt; ++i) {if(i < k)swap(A[i],A[k]);for(int j = cnt >> 1; (k ^= j) < j; j >>= 1);}int i,j;Complex w,wn,t;for(int k = 2; k <= cnt; k <<= 1)for(wn = Complex(cos(2 * PI / k),flag * sin(2 * PI / k)),i = 0; i < cnt; i += k)for(w = 1.0,j = 0; j < k >> 1; ++j,w *= wn) {t = w * A[i + j + (k >> 1)];A[i + j + (k >> 1)] = A[i + j] – t;A[i + j] += t;}if(!~flag)for(int i = 0; i < cnt; ++i)A[i] /= cnt;}int l1,l2;Complex A[MAX],B[MAX];int main(){cin >> l1 >> l2;for(int i = 0; i <= l1; ++i)scanf("%lf",&A[i].x);for(int i = 0; i <= l2; ++i)scanf("%lf",&B[i].x);int l = l1 + l2,cnt;for(cnt = 1; cnt <= l; cnt <<= 1);FFT(A,cnt,1),FFT(B,cnt,1);for(int i = 0; i < cnt; ++i)A[i] *= B[i];FFT(A,cnt,-1);for(int i = 0; i <= l1 + l2; ++i)printf("%d%c",int(A[i].x + .5)," \n"[i == l1 + l2]);return 0;}

,人之所以有一张嘴,而有两只耳朵,原因是听的要比说的多一倍。

UOJ #34 多项式乘法 FFT快速傅立叶变换

相关文章:

你感兴趣的文章:

标签云: