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

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


CODE:


#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 1000010
using 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;
}


你可能感兴趣的:(fft,uoj)