FFT(模板)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yz467796454/article/details/82020880

 

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
//typedef complex<double> C;
const int maxn = 1 << 18;
struct C
{
    double a,b;
    C(){}
    C(double a,double b):a(a),b(b){}
    C operator = (int a){*this=C(a*1.0,0);return *this;}
    C operator + (const C &t){return C(a+t.a,b+t.b);}
    C operator - (const C &t){return C(a-t.a,b-t.b);}
    C operator * (const C &t){return C(a*t.a-b*t.b,a*t.b+b*t.a);}
};

C wn(int n, int f)
{
    return C(cos(acos(-1.0) / n), f*sin((acos(-1.0)) / n));
}
C inv(int n)
{
    return C(1.0 / n, 0);
}
C a[maxn], b[maxn], c[maxn];
int g[maxn];
void FFT(C *a, int n, int f)
{
    for (int i = 0; i < n; i++)if (i > g[i])swap(a[i], a[g[i]]);
    for (int i = 1; i < n; i <<= 1)
    {
        C w = wn(i, f), x, y;
        for (int j = 0; j < n; j += i + i)
        {
            C e; e = 1;
            for (int k = 0; k < i; e = e * w, k++)
            {
                x = a[j + k];
                y = a[j + k + i] * e;
                a[j + k] = x + y;
                a[j + k + i] = x - y;
            }
        }
    }
    if (f == -1)
    {
        C Inv = inv(n);
        for (int i = 0; i < n; i++)a[i] = a[i] * Inv;
    }
}
void conv(C *a, int n, C *b, int m, C *c)
{
    int k = 0, s = 2;
    while ((1 << k) < max(n, m) + 1)k++, s <<= 1;
    for (int i = 1; i < s; i++)g[i] = (g[i / 2] / 2) | ((i & 1) << k);
    FFT(a, s, 1);
    FFT(b, s, 1);
    for (int i = 0; i < s; i++)c[i] = a[i] * b[i];
    FFT(c, s, -1);
}
int main(){
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i <= n; i++)scanf("%lf", &a[i].a);
    for (int i = 0; i <= m; i++)scanf("%lf", &b[i].a);
    conv(a, n, b, m, c);
    for (int i = 0; i <= n + m; i++)printf("%d ", (int)(c[i].a+ 0.5));
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1 << 18;
typedef complex<double> C;
C wn(int n, int f)
{
    return C(cos(acos(-1.0) / n), f*sin((acos(-1.0)) / n));
}
C inv(int n)
{
    return C(1.0 / n, 0);
}
C a[maxn], b[maxn], c[maxn];
int g[maxn];
void FFT(C *a, int n, int f)
{
    for (int i = 0; i < n; i++)if (i > g[i])swap(a[i], a[g[i]]);
    for (int i = 1; i < n; i <<= 1)
    {
        C w = wn(i, f), x, y;
        for (int j = 0; j < n; j += i + i)
        {
            C e; e = 1;
            for (int k = 0; k < i; e = e * w, k++)
            {
                x = a[j + k];
                y = a[j + k + i] * e;
                a[j + k] = x + y;
                a[j + k + i] = x - y;
            }
        }
    }
    if (f == -1)
    {
        C Inv = inv(n);
        for (int i = 0; i < n; i++)a[i] = a[i] * Inv;
    }
}
void conv(C *a, int n, C *b, int m, C *c)
{
    int k = 0, s = 2;
    while ((1 << k) < max(n, m) + 1)k++, s <<= 1;
    for (int i = 1; i < s; i++)g[i] = (g[i / 2] / 2) | ((i & 1) << k);
    FFT(a, s, 1);
    FFT(b, s, 1);
    for (int i = 0; i < s; i++)c[i] = a[i] * b[i];
    FFT(c, s, -1);
}
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i <= n; i++)scanf("%lf", &a[i]);
    for (int i = 0; i <= m; i++)scanf("%lf", &b[i]);
    conv(a, n, b, m, c);
    for (int i = 0; i <= n + m; i++)printf("%d ", (int)(c[i].real() + 0.5));
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yz467796454/article/details/82020880