首页 > 代码库 > spoj VFMUL FFT快速傅立叶变换模板题

spoj VFMUL FFT快速傅立叶变换模板题

  题意;求两个数相乘。

  第一次写非递归的fft,因为一个数组开小了调了两天TAT。

#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>#include<cmath>using namespace std;#define PI 3.1415926535897932384#define MAXN 1200000#pragma optimize("O2")struct Complex{        double x,y;        Complex(){};        Complex(double x,double y):x(x),y(y){};        void init(double x,double y)        {                this->x=x;this->y=y;        }        Complex operator +(Complex a)        {                Complex ret(x + a.x, y + a.y);                return ret;        }        Complex operator -(Complex a)        {                Complex ret(x - a.x, y - a.y);                return ret;        }        Complex operator *(Complex a)        {                Complex ret(x*a.x - y*a.y, x*a.y + y*a.x);                return ret;        }        Complex operator /(double v)        {                Complex ret(x/v,y/v);                return ret;        }        Complex operator =(double x)        {                this->x=x;                return *this;        }        void operator -=(Complex a)        {                this->x-=a.x;                this->y-=a.y;        }        void operator +=(Complex a)        {                this->x+=a.x;                this->y+=a.y;        }};char ss[MAXN];int t1[MAXN],t2[MAXN];int pp[MAXN];Complex ww[MAXN][2];Complex g1[MAXN],g2[MAXN];long long res[MAXN];int n;void dft(Complex g[],int len,int sign){        Complex t;        for (int i=1;i<len;i<<=1)        {                for (int j=0;j<len;j+=(i<<1))                {                        for (int k=0;k<i;k++)                        {                                t=g[j+k];                                g[j+k]=g[j+k]+g[j+k+i]*ww[k*((n>>1)/i)][sign];                                g[j+k+i]=t-g[j+k+i]*ww[k*((n>>1)/i)][sign];                        }                }        }}int main(){        freopen("input.txt","r",stdin);        //    freopen("output.txt","w",stdout);        int i,j,k,x,y,z,m;        int n1,n2;        int nn;        scanf("%d",&nn);        while (nn--)        {                scanf("%s",ss);                m=strlen(ss);                for (i=0;i<m;i++)                        t1[(m-i-1)/5]=t1[(m-i-1)/5]*10+ss[i]-0;                n1=(m-1)/5+1;                scanf("%s",ss);                m=strlen(ss);                for (i=0;i<m;i++)                        t2[(m-i-1)/5]=t2[(m-i-1)/5]*10+ss[i]-0;                n2=(m-1)/5+1;                n=max(n1,n2);                while (n!=(n&(-n)))n-=n&(-n);                n<<=2;                for (i=0;i<n;i++)                        for (j=n>>1,x=1;j;j>>=1,x<<=1)                                if (i&j)pp[i]+=x;                for (i=0;i<n1;i++)g1[pp[i]].x=t1[i];                for (i=0;i<n2;i++)g2[pp[i]].x=t2[i];                for (i=0;i<=n;i++)                {                        ww[i][0].init(cos(2*PI*i/n), -sin(2*PI*i/n));                        ww[i][1].x=ww[i][0].x;                        ww[i][1].y=-ww[i][0].y;                }                dft(g1,n,0);                dft(g2,n,0);                for (i=0;i<n;i++)g2[i]=g1[i]*g2[i];                for (i=0;i<n;i++)g1[pp[i]]=g2[i];                dft(g1,n,1);                for (i=0;i<n;i++)res[i]=(long long)(g1[i].x/n+0.5);                for (i=0;i<n;i++)res[i+1]+=res[i]/100000,res[i]%=100000;                m=n;                while (m && !res[m-1])m--;                printf("%d",(int)res[m-1]);                for (i=m-2;i>=0;i--)                        printf("%05d",(int)res[i]);                printf("\n");                memset(t1,0,sizeof(t1[0])*n);                memset(t2,0,sizeof(t2[0])*n);                memset(pp,0,sizeof(pp[0])*n);                memset(res,0,sizeof(res[0])*n);                memset(g1,0,sizeof(g1[0])*n);                memset(g2,0,sizeof(g2[0])*n);        }}

 

spoj VFMUL FFT快速傅立叶变换模板题