由于不会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)<<" ";//注意这里四舍五入
}
}