• [学习]快速傅里叶变换


    快速傅里叶变换用于加速多项式的乘法,复杂度O(nlogn),例题:http://uoj.ac/problem/34

    详解:https://www.cnblogs.com/RabbitHu/p/FFT.html

    模板:

    #include<bits/stdc++.h>
    #define PI acos(-1.0)
    using namespace std;
    
    struct Complex{
        double real,img;
        Complex(const double &real=0.0,const double &img=0.0):real(real),img(img){}
        Complex operator + (const Complex &c) const {return Complex(real+c.real,img+c.img); }
        Complex operator - (const Complex &c) const {return Complex(real-c.real,img-c.img); }
        Complex operator * (const Complex &c) const {return Complex(real*c.real-img*c.img,real*c.img+img*c.real); }
    }a[100005*4],b[100005*4],omg[100005*4],inv[100005*4];//长度为fn的大小
    
    void init(int n){
        for(int i = 0; i < n; i++){
            omg[i] = Complex(cos(2 * PI * i / n), sin(2 * PI * i / n));
            inv[i] = Complex(cos(2 * PI * i / n), -1.0*sin(2.0 * PI * i / n));
        }
    }
    
    void fft(Complex *a,int n,Complex *omg){
        int lim = 0;
        while((1 << lim) < n) lim++;
        for(int i = 0; i < n; i++){
            int t = 0;
            for(int j = 0; j < lim; j++)
                if((i >> j) & 1) t |= (1 << (lim - j - 1));
            if(i < t) swap(a[i], a[t]);
        }
    
        for(int l = 2; l <= n; l *= 2){
            int m = l / 2;
            for(Complex *p = a; p != a + n; p += l)
            for(int i = 0; i < m; i++){
                Complex t = omg[n / l * i] * p[i + m];
                p[i + m] = p[i] - t;
                p[i] = p[i] + t;
            }
        }
    }
    
    int main()
    {
        int n,m;scanf("%d%d",&n,&m);
        for(int i=0;i<=n;i++) scanf("%lf",&a[i].real);
        for(int i=0;i<=m;i++) scanf("%lf",&b[i].real);
    
        int fn=1;//fn-1次多项式,fn=2^k
        while(fn<=n+m) fn<<=1;
        init(fn);
    
        fft(a,fn,omg);
        fft(b,fn,omg);
    
        for(int i=0;i<fn;i++) a[i]=a[i]*b[i];
        fft(a,fn,inv);
    
        for(int i=0;i<=n+m;i++) printf("%d ",int(a[i].real/fn+0.5));
        puts("");
    
        return 0;
    }
  • 相关阅读:
    指定时间的月初和月末一天的写法
    EF写distinct
    服务的调试和安装
    EF写INNER JOIN 链接
    BZOJ 1825: [JSOI2010]蔬菜庆典
    P4171 [JSOI2010]满汉全席
    Educational Codeforces Round 71 (Rated for Div. 2) Solution
    P4292 [WC2010]重建计划
    P3724 [AH2017/HNOI2017]大佬
    P5504 [JSOI2011]柠檬
  • 原文地址:https://www.cnblogs.com/lllxq/p/11135155.html
Copyright © 2020-2023  润新知