• HDU1402:A * B Problem Plus——题解


    http://acm.hdu.edu.cn/showproblem.php?pid=1402

    给出两个高精度正整数,求它们的积,最长的数长度不大于5e4。

    FFT裸题,将每个数位看做是多项式的系数即可。

    我们最后就是要求出两个多项式相乘的系数。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    typedef double dl;
    const dl pi=acos(-1.0);
    const int N=2e5+10;
    struct complex{//定义复数 
        dl x,y;
        complex(dl xx=0.0,dl yy=0.0){
            x=xx;y=yy;
        }
        complex operator +(const complex &b)const{
            return complex(x+b.x,y+b.y);
        }
        complex operator -(const complex &b)const{
            return complex(x-b.x,y-b.y);
        }
        complex operator *(const complex &b)const{
            return complex(x*b.x-y*b.y,x*b.y+y*b.x);
        }
    };
    void FFT(complex a[],int n,int on){
        for(int i=1,j=n>>1;i<n-1;i++){
            if(i<j)swap(a[i],a[j]);
            int k=n>>1;
            while(j>=k){j-=k;k>>=1;}
            if(j<k)j+=k;
        }
        for(int i=2;i<=n;i<<=1){
            complex res(cos(-on*2*pi/i),sin(-on*2*pi/i));
            for(int j=0;j<n;j+=i){
                complex w(1,0);
                for(int k=j;k<j+i/2;k++){
                    complex u=a[k],t=w*a[k+i/2];
                    a[k]=u+t;
                    a[k+i/2]=u-t;
                    w=w*res;
                }
            }
        }
        if(on==-1)
            for(int i=0;i<n;i++)a[i].x/=n;
    }
    char a[N],b[N];
    complex x[N],y[N];
    int ans[N];
    int main(){
        while(cin>>a>>b){
            int len1=strlen(a),len2=strlen(b);
            int n=1;
            while(n<len1*2||n<len2*2)n<<=1;
            for(int i=0;i<len1;i++)x[i]=complex(a[len1-1-i]-'0',0);
            for(int i=len1;i<n;i++)x[i]=complex(0,0);
            for(int i=0;i<len2;i++)y[i]=complex(b[len2-1-i]-'0',0);
            for(int i=len2;i<n;i++)y[i]=complex(0,0);
            FFT(x,n,1);FFT(y,n,1);
            for(int i=0;i<n;i++)x[i]=x[i]*y[i];
            FFT(x,n,-1);
            for(int i=0;i<n;i++)ans[i]=(int)(x[i].x+0.5);
            for(int i=0;i<n;i++){
                ans[i+1]+=ans[i]/10;
                ans[i]%=10;
            }
            n=len1+len2-1;
            while(ans[n]<=0&&n>0)n--;
            for(int i=n;i>=0;i--)printf("%d",ans[i]);
            puts("");
        }
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

    +本文作者:luyouqi233。               +

    +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    P1428 小鱼比可爱
    P5727 【深基5.例3】冰雹猜想
    P1427 小鱼的数字游戏
    P1047 [NOIP2005 普及组] 校门外的树
    P5729 工艺品制作
    P5728 【深基5.例5】旗鼓相当的对手
    CodeSmith使用和语法简介
    系统缓存
    FLV视频转换的利器 ffmpeg.exe
    Vs.Net方向将Excel数据导入到数据库
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/8448969.html
Copyright © 2020-2023  润新知