• FFT学习笔记


    (FFT)学习笔记

    因为已经有比我写的好的了,所以这里就不会重头讲,只讲一些自己需要用的而已。

    YYC大佬写的

    (FFT)解决什么呢?解决两个多项式快速相乘的问题。

    我们设第一个多项式为(F(x)),第二个多项式为(G(x)).

    多项式(F(x))的项数为(n) ,多项式(G(x))的项数为(m).

    乘出来的多项式为(W(x)).项数为((n+m-1)).

    入门基本:初中一年级学历

    DFT

    过程:把系数表达转换为点值表达

    相信大家都学过了待定系数法

    把一个多项式转换为点值表达应该不难

    显而易见,把一个(n)次多项式转换为点值表达,需要(n+1)个坐标。

    我们把这些(F(x))坐标记为:((x_0,y_0);(x_1,y_1);(x_2,y_2)……)

    我们把这些(G(x))坐标记为:((x_0,y^*_0);(x_1,y^*_1);(x_2,y^*_2)……)

    那么(W(x))坐标就为:((x_0,y_0*y^*_0);(x_1,y_1*y^*_1);(x_2,y_2*y^*_2)……)

    那么我们的问题就在于如何将(F)(G)转换为点值表达。

    求出(F)(G)的点值表达,就可以快速算出(W)的点值表达了。

    复数

    在学习DFT之前,还要先学学这个——复数

    虚数

    定义:(i^2=-1)

    实数和虚数的组合就是复数,记为(a+bi)

    PS:(i^2)要化简为(-1)

    复数的 模长 指它的长度(到原点的距离),辐角 指它与原点的连线,与 (x) 轴(逆时针)的夹角。如图,复数(2+3i) 的模长和辐角都已标出(引用longlongzhu123的博客)

    img

    代码定义复数

    结构体存储:一个存实数部,一个存虚数

    struct Complex{
    	double r,i;
    	Complex():r(0),i(0){}						//初始化
    	Complex(double R,double I) : r(R),i(I){}	//同r=R,i=I,给一个虚数赋值
    	Complex(const Complex& c) : r(c.r),i(c.i){}	//等同r=c.r,i=c.i
    };
    

    复数运算

    我们设两个复数(x,y), (x=a_0+b_0i)(y=a_1+b_1i) . 一个实数(k) .

    加法

    [x+y=(a_0+b_0i)+(a_1+b_1i)=(a_0+a_1)+(b_0+b_1)i ]

    减法

    [x-y=(a_0+b_0i)-(a_1+b_1i)=(a_0-a_1)+(b_0-b_1)i ]

    乘法

    [x*k=(a_0+b_0i)*k=a_0k+b_0ki ]

    [x*y=(a_0+b_0i)*(a_1+b_1i)=a_0a_1+a_0b_1i+a_1b_0i-b_0b_1 ]

    [x*y=(a_0a_1-b_0b_1)+(a_0b_1+a_1b_0)i ]

    运算的几何意义(非重要)

    (引用longlongzhu123的博客)

    加法

    例子:((2+3i)+(3+1i)=5+4i)

    img

    意义:发现什么了吗?没有?看看那条虚线跟$ 2+3i$ 有什么关系?没错。虚线与 (2+3i)平行。(2+3i)(3+1i)相加的结果可以看成在 (3+1i) 的端点处向上数$3 $格,向右数 (2) 格得到的点。或者说是两个复数所组成平行四边形的一条对角线。(理解一下这句话)

    乘法

    复数乘法也有几何意义。一句话:模长相乘,辐角相加

    img

    代码实现运算

    重载看不到不要紧,直接看(return)就ok了。(记住返回的也是复数,用结构体存)

    inline Complex operator+(const Complex&a,const Complex&b){return Complex(a.r+b.r,a.i+b.i);}	//复数+
    inline Complex operator-(const Complex&a,const Complex&b){return   Complex(a.r-b.r,a.i-b.i);} //复数-
    inline Complex operator*(const Complex&a,const Complex&b){			//复数*
        return Complex(a.r*b.r - a.i*b.i , a.r*b.i + b.r*a.i );
    }
    

    单位根

    单位圆:在复平面上一个模长(1) ,长下面这个样子。

    img

    n次单位根:把单位圆平分成(n)份,取其中第一份(从x轴正半轴开始逆时针平分)

    例子:(3)次单位根,长下面那样,(B)点即为(3)次单位根

    img

    我们把n次单位根记为:(omega_n)(omega_n^1)

    那剩下的(n-1)个点(指上面的(A)(C)点)怎么表示呢?

    我们发现,(B)点是从(x)轴正半轴开始逆时针数的第一个点((A)点是第(0)个,记作(omega^0_n)),所以它记作(omega^1_n),那么(C)点是第二个点,它记作(omega^2_n)。同理,第(k)个点就叫(omega^k_n),另外(omega^k_n=(omega_n)^k)

    单位根的性质

    (引用至command_block的blog)

    单位根的世界,就是一个单位圆。

    -1. $ forall x:omega_n^0=1(,(翻译成人话:对于任意的n,)omega_n^0=1$)

    0.(omega^k_n=(omega_n)^k)

    1.(omega_n^j*omega_n^k=omega_n^{j+k})

    2.(omega_{2n}^{2k}=omega_n^k)

    3.当(n)为偶数时,(omega_n^{(k+n/2)}=-omega_n^k)

    4.(sum_{i=1}^{n} omega_n^i=0)

    5.(omega_n^1=(cos(frac{2pi}{n}),sin(frac{2pi}{n}))) (注:左边为实数部,右边为虚数部)

    6.(omega_n^k=omega_n^{k\%n})

    [F(omega^k_n )=Fl(omega^k_{n/2})+omega^k_nFR(omega^k_{n/2}) ]

    [F(omega^{k+n/2}_n)=FL(omega^k_{n/2}-omega^k_nFR(omega^k_{n/2})) ]

  • 相关阅读:
    [转载]Centos7.x下环境搭建(一)--yum方式安装mysql5.7
    树上分治
    [SPOJ2666]QTREE4
    [SPOJ375]QTREE
    [SPOJ1825]FTOUR2
    [POJ1741]Tree
    [LG-P5350]序列
    [COCI 2014/2015 #3]KAMIONI
    [SHOI2014]神奇化合物
    [GXOI/GZOI2019]旧词
  • 原文地址:https://www.cnblogs.com/hyfhaha/p/10887243.html
Copyright © 2020-2023  润新知