1. 程式人生 > >[模板]快速傅立葉變換 FFT

[模板]快速傅立葉變換 FFT

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define reg register
inline int read() {
    int res = 0;char ch = getchar();bool fu = 0;
    while(!isdigit(ch)) fu |= (ch == '-'), ch = getchar();
    while(isdigit(ch)) res = (res << 3
) + (res << 1) + (ch ^ 48), ch = getchar(); return fu ? - res : res; } namespace BriMon { #define N 1100005 const double Pi = 3.14159265358979323846264338327950; int n, m, rev[N<<2]; struct cmplx { double x, y; cmplx(double a = 0, double b = 0) {x = a, y = b;} friend cmplx
operator + (cmplx a, cmplx b) { return cmplx(a.x + b.x, a.y + b.y); } friend cmplx operator - (cmplx a, cmplx b) { return cmplx(a.x - b.x, a.y - b.y); } friend cmplx operator * (cmplx a, cmplx b) { return cmplx(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);} } b[N<<2], c[N<<2];
void fft(cmplx *f, int op) { for (reg int i = 0 ; i < n ; i ++) if (i < rev[i]) swap(f[i], f[rev[i]]); for (reg int p = 2 ; p <= n ; p <<= 1) { int len = p >> 1; cmplx tmp = cmplx(cos(Pi / len), op * sin(Pi / len)); for (reg int k = 0 ; k < n ; k += p) { cmplx w = cmplx(1, 0); for (reg int l = k ; l < k + len ; l ++) { cmplx __tmp = w * f[l + len]; f[l + len] = f[l] - __tmp; f[l] = f[l] + __tmp; w = w * tmp; } } } } int main() { n = read(), m = read(); for (reg int i = 0 ; i <= n ; i ++) scanf("%lf", &b[i].x); for (reg int i = 0 ; i <= m ; i ++) scanf("%lf", &c[i].x); for (m += n, n = 1 ; n <= m ; n <<= 1); for (reg int i = 0 ; i < n ; i ++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? n >> 1 : 0); fft(b, 1), fft(c, 1); for (reg int i = 0 ; i < n ; i ++) b[i] = b[i] * c[i]; fft(b, -1); for (reg int i = 0 ; i <= m ; i ++) printf("%.0lf ", fabs(b[i].x) / n); return 0; } } int zZh = BriMon :: main(); int main() {return 0;}