多项式(FFT)

由于不会markdown
这里只提供代码和讲解代码,思想可以去别的博客里看
多项式乘法
FFT

#include<iostream>
#include<cstdio>
#include<cmath> 
using namespace std;
const int N = 4e6 + 7;
const double Pi = acos(-1.0);
struct complex{
	double x,y;
	complex (double xx = 0, double yy = 0) {
		x = xx;
		y = yy;
	}
}a[N],b[N];
int n, m;
complex operator +(complex a,complex b) { return complex(a.x + b.x, a.y + b.y); };
complex operator -(complex a,complex b) { return complex(a.x - b.x, a.y - b.y); };
complex operator *(complex a,complex b) { return complex(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x); };

void FFT(int limit, complex *a, int f){
	if(limit == 1) return;
	complex a1[(limit >> 1) + 1], a2[(limit >> 1) + 1];
	for(int i = 0; i <= limit; i += 2){
		a1[i >> 1] = a[i];
		a2[i >> 1] = a[i + 1];
	}
	FFT(limit >> 1, a1, f);
	FFT(limit >> 1, a2, f);
	
	complex Wn = complex(cos(2.0 * Pi / limit), f * sin(2.0 * Pi / limit)), w = complex(1, 0);//单位根
	for(int i = 0; i < (limit >> 1); i++, w = w * Wn){//这里写小于等于是不对的,一定是小于哦,小于等于的话是不是n/2的时候会被算两遍?
		a[i] = a1[i] + w * a2[i];
		a[i + (limit >> 1)] = a1[i] - w * a2[i];	
	}
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i = 0; i <= n; i++) scanf("%lf", &a[i].x);
	for(int i = 0; i <= m; i++) scanf("%lf", &b[i].x);
	int limit = 1;
	while(limit <= n + m) limit <<= 1;//一定要大于等于n+m;
	FFT(limit, a, 1);
	FFT(limit, b, 1);
	
	for(int i = 0; i <= limit; i++) a[i] = a[i] * b[i];
	FFT(limit, a, -1);
	for(int i = 0; i <= n + m; i++){
		cout<<(int)(a[i].x/limit+0.5)<<" ";//注意这里四舍五入
	}
} 
posted @ 2021-01-11 19:54  Aswert  阅读(91)  评论(0编辑  收藏  举报