P3803 多项式乘积(FFT)
Posted jpphy0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3803 多项式乘积(FFT)相关的知识,希望对你有一定的参考价值。
目录
问题
P3803 多项式乘积 - https://www.luogu.com.cn/problem/P3803
分析
- fft
代码
#include <bits/stdc++.h>
using namespace std;
const double DFT = 2.0, IDFT = -2.0, PI = acos(-1.0);
const int MXN = 1e6+10;
int n, m, r[MXN<<2];
struct Complex
double r, i;
Complex(double _r = 0, double _i = 0) : r(_r), i(_i)
Complex operator + (const Complex & x)
return Complex(r + x.r, i + x.i);
Complex operator += (const Complex & x)
r += x.r, i += x.i;
return *this;
Complex operator - (const Complex & x)
return Complex(r - x.r, i - x.i);
Complex operator -= (const Complex & x)
r -= x.r, i -= x.i;
return *this;
Complex operator * (const Complex & x)
return Complex(r * x.r - i * x.i, r * x.i + i * x.r);
Complex operator *= (const Complex & x) // x is this
double xr = x.r, xi = x.i, tr = r;
r = r * xr - i * xi, i = tr * xi + i * xr;
return *this;
void print(char pad)
printf("%d%c", (int)(r+0.5), pad);
p1[MXN<<2], p2[MXN<<2];
void fft(Complex p[], int len, double mode)
for(int i = 0; i < len; i++) if(i < r[i]) swap(p[i], p[r[i]]);
for(int i = 2, mid = 1; i <= len; i <<= 1, mid <<= 1)
Complex wn(cos(mode*PI/i), sin(mode*PI/i));
for(int s = 0; s < len; s += i)
Complex w(1.0, 0.0);
for(int t = s; t < s + mid; ++t, w *= wn)
Complex l = p[t], r = w*p[t+mid];
p[t] = l + r, p[t+mid] = l - r;
if(mode == DFT) return;
for(int i = 0; i < len; ++i) p[i].r /= len;
int main()
int len, bit;
for(int i = 0; i < MXN; ++i) p1[i] = p2[i] = 0, 0;
scanf("%d%d", &n, &m);
for(int i = 0; i <= n; ++i) scanf("%lf", &p1[i].r), p1[i].i = 0;
for(int i = 0; i <= m; ++i) scanf("%lf", &p2[i].r), p2[i].i = 0;
bit = 1, len = n+m;
while(len >>= 1) ++bit;
len = 1 << bit;
for(int i = 0; i < len; ++i) r[i]=(r[i>>1]>>1)|((i&1)<<(bit-1));
fft(p1, len, DFT), fft(p2, len, DFT);
for(int i = 0; i < len; ++i) p1[i] *= p2[i];
fft(p1, len, IDFT);
len = n + m;
for(int i = 0; i < len; ++i) p1[i].print(' ');
p1[len].print('\\n');
return 0;
#include <bits/stdc++.h>
using namespace std;
typedef complex<double> cd;
const double DFT = 2.0, IDFT = -2.0, PI = acos(-1.0);
const int MXN = 1e6+10;
int n, m, r[MXN<<2];
cd p1[MXN<<2], p2[MXN<<2];
void fft(cd p[], int len, double mode)
for(int i = 0; i < len; i++) if(i < r[i]) swap(p[i], p[r[i]]);
for(int i = 2, mid = 1; i <= len; i <<= 1, mid <<= 1)
cd wn(cos(mode*PI/i), sin(mode*PI/i));
for(int s = 0; s < len; s += i)
cd w(1.0, 0.0);
for(int t = s; t < s + mid; ++t, w *= wn)
cd l = p[t], r = w*p[t+mid];
p[t] = l + r, p[t+mid] = l - r;
if(mode == DFT) return;
for(int i = 0; i < len; ++i) p[i] /= len;
int main()
int len, bit;
scanf("%d%d", &n, &m);
for(int i = 0; i < MXN; ++i) p1[i] = p2[i] = 0;
for(int x, i = 0; i <= n; ++i) scanf("%d", &x), p1[i] = x;
for(int x, i = 0; i <= m; ++i) scanf("%d", &x), p2[i] = x;
bit = 1, len = n+m;
while(len >>= 1) ++bit;
len = 1 << bit;
for(int i = 0; i < len; ++i) r[i]=(r[i>>1]>>1)|((i&1)<<(bit-1));
fft(p1, len, DFT), fft(p2, len, DFT);
for(int i = 0; i < len; ++i) p1[i] *= p2[i];
fft(p1, len, IDFT);
len = n + m;
for(int i = 0; i < len; ++i) printf("%d ", (int)(p1[i].real()+0.5));
printf("%d", (int)(p1[len].real()+0.5));
return 0;
以上是关于P3803 多项式乘积(FFT)的主要内容,如果未能解决你的问题,请参考以下文章