zoukankan      html  css  js  c++  java
  • 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("
    ");
                    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);
            }
    }
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    Ubuntu--更改国内镜像源(阿里、网易、清华、中科大)
    mui做直播推流及时分秒计时器的实现用例
    远程连接
    Dockerfile
    Docker-compose
    Docker基础命令
    python中执行其他的python脚本(三):
    python中执行其他的python脚本(二):
    python中执行其他的python脚本(一):
    树莓派4B源码编译opencv3.4.1
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4171455.html
Copyright © 2011-2022 走看看