FFT P3803 [模板]多项式乘法
FFT(快速傅里叶变化) 可以加速求多项式乘法。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
const int N = 4e6 + 105;
const int mod = 1e9 + 7;
const double Pi = acos(- 1.0);
const ll INF = 1e16;
inline int read() {
char ch = getchar(); int x = 0, f = 1;
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while ('0' <= ch && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
struct complex {
double x, y;
complex (double xx = 0, double yy = 0) {x = xx, y = yy;}
} a[N], b[N];
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);}
int l, r[N];
int len = 1;
void FFT(complex a[], int inv){
for(int i = 0; i < len; ++ i)
if(i < r[i])
swap(a[i], a[r[i]]);
complex w, Wn, x, y;
for(int mid = 1; mid < len; mid <<= 1){
Wn.x = cos(Pi / mid) , Wn.y = inv * sin(Pi / mid);
for(int Size = mid << 1, L = 0; L < len; L += Size){
w.x = 1, w.y = 0;
for(int i = 0; i < mid; i ++, w = w * Wn){
x = a[L + i], y = w * a[L + mid + i];
a[L + i] = x + y;
a[L + mid + i] = x - y;
}
}
}
}
int main()
{
int n, m;
n = read(), m = read();
for(int i = 0; i <= n; ++ i) a[i].x = read();
for(int i = 0; i <= m; ++ i) b[i].x = read();
while(len <= n + m) len <<= 1, l ++;
for(int i = 0; i < len; ++ i)
r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
FFT(a, 1), FFT(b, 1);
for(int i = 0; i <= len; ++ i) a[i] = a[i] * b[i];
FFT(a, -1);
for(int i = 0; i <= n + m ; ++ i){
printf("%d ",(int)(a[i].x / len + 0.5));
}
return 0;
}