题目链接:P3803 【模板】多项式乘法(FFT)
题意
给定一个 \(n\) 次多项式 \(F(x)\) 和一个 \(m\) 次多项式 \(G(x)\),求 \(F(x)\) 和 \(G(x)\) 的卷积。
思路
FFT
又是一道 \(FFT\) 的模板题,不过用递归的 \(FFT\) 会超时。
代码
#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1);
typedef complex<double> Complex;
const int maxn = 3e6 + 10;
Complex a[maxn], b[maxn];
int m, n;
int bit = 2, rev[maxn];
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
void get_rev(){
while(bit <= n + m) bit <<= 1;
for(int i = 0; i < bit; ++i) {
rev[i] = (rev[i >> 1] >> 1) | (bit >> 1) * (i & 1);
}
}
void FFT(Complex *a, int op) {
for(int i = 0; i < bit; ++i) {
if(i < rev[i]) swap(a[i], a[rev[i]]);
}
for(int mid = 1; mid < bit; mid <<= 1) { // 左右两部分的区间长度
Complex wn = Complex(cos(PI / mid), op * sin(PI / mid)); // 单位复数根
for(int j = 0; j < bit; j += mid<<1) { // 一组一组处理
Complex w(1, 0);
for(int k = 0; k < mid; ++k, w = w * wn) {
Complex x = a[j + k], y = w * a[j + k + mid]; // 蝴蝶操作
a[j + k] = x + y, a[j + k + mid] = x - y;
}
}
}
}
int main() {
n = read(), m = read();
for(int i = 0; i <= n; ++i) {
a[i] = read();
}
for(int i = 0; i <= m; ++i) {
b[i] = read();
}
get_rev();
FFT(a, 1);
FFT(b, 1);
for(int i = 0; i <= bit; ++i) {
a[i] *= b[i];
}
FFT(a, -1);
for(int i = 0; i <= n + m; ++i) {
printf("%d ", (int)(a[i].real() / bit + 0.5));
}
printf("\n");
return 0;
}