HDU 1402 A * B Problem Plus

来源:互联网 发布:怎么盗取淘宝装修代码 编辑:程序博客网 时间:2024/06/18 14:32

A * B Problem Plus

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Problem Description
Calculate A * B.
Input
Each line will contain two integers A and B. Process to end of file.
Note: the length of each integer will not exceed 50000.
Output
For each case, output A * B in one line.
Sample Input
1
2
1000
2
Sample Output
2
2000
Author
DOOM III

单纯的高精度乘法不知道会不会被卡(看数据的话应该会被卡),刚刚学的快速傅里叶变换,尝试搞了一下,还是看题解~

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cmath>using namespace std;const double eps=(1e-8);typedef long long LL;const double PI = acos(-1.0);struct ComePlx{    double real,image;    ComePlx(double _real,double _image){        real = _real;        image = _image;    }    ComePlx(){}};ComePlx operator + (const ComePlx &c1,const ComePlx &c2){    return ComePlx(c1.real+c2.real,c1.image+c2.image);}ComePlx operator - (const ComePlx &c1,const ComePlx &c2){    return ComePlx(c1.real-c2.real,c1.image-c2.image);}ComePlx operator * (const ComePlx &c1, const ComePlx &c2)  {      return ComePlx(c1.real*c2.real - c1.image*c2.image,                 c1.real*c2.image + c1.image*c2.real);}int rev(int id,int len){    int ret=0;    for(int i=0;(1<<i) < len;i++){        ret <<= 1;        if(id & (1<<i)) ret |= 1;    }    return ret; }ComePlx A[140000];void FFT(ComePlx* a,int len,int DFT){    for(int i=0;i<len;i++)        A[rev(i,len)]=a[i];    for(int s=1;(1<<s)<=len;s++){        int m=(1<<s);        ComePlx wm =ComePlx(cos(DFT*2*PI/m),sin(DFT*2*PI/m));        for(int k=0;k<len;k+=m){            ComePlx w = ComePlx(1,0);            for(int j=0;j < (m>>1);j++){                  ComePlx t = w*A[k + j + (m >> 1)];                ComePlx u = A[k + j];                A[k + j] = u + t;                A[k + j + (m >> 1)] = u - t;                w = w*wm;              }          }    }    if(DFT == -1) for(int i=0;i<len;i++){        A[i].real /= len,A[i].image /= len;    }    for(int i=0;i<len;i++) a[i] = A[i];    return ;}char numA[50010],numB[50010];ComePlx a[140000],b[140000];int ans[140000];int main(){    while(~scanf("%s",numA)){        int lenA=strlen(numA);        int sa=0;        while((1 << sa) < lenA) sa++;        scanf("%s",numB);        int lenB=strlen(numB);        int sb=0;        while((1 << sb) < lenB) sb++;        int len = (1 << ( max(sa,sb) + 1));        for(int i=0;i<len;i++){            if(i < lenA) a[i]=ComePlx(numA[lenA-i-1]-'0',0);            else a[i]=ComePlx(0,0);            if(i < lenB) b[i]=ComePlx(numB[lenB-i-1]-'0',0);            else b[i]=ComePlx(0,0);        }        FFT(a,len,1);        FFT(b,len,1);//A,B换成点值表示        for(int i=0;i<len;i++) a[i]=a[i]*b[i];        FFT(a,len,-1);        for(int i=0;i<len;i++) ans[i]=(int)(a[i].real+0.5);        //取整误差的处理        for(int i=0;i<len-1;i++){//进位问题            ans[i+1] += ans[i]/10;            ans[i] %= 10;        }        bool flag=0;        for(int i=len-1;i>=0;i--){            if(ans[i]) printf("%d",ans[i]),flag=1;            else if(flag||i==0) printf("0");        }        putchar('\n');    }    return 0;}
0 0
原创粉丝点击