codevs 3123 高精度练习之超大整数乘法

Posted on 2016-08-12 09:34  ziliuziliu  阅读(179)  评论(0编辑  收藏  举报

fft。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<complex>
#include<cmath>
#include<algorithm>
#define maxn 300500
#define pi acos(-1)
using namespace std;
typedef complex<double> E;
char s[maxn];
int l1,l2,n=0,m,l=0,c[maxn],r[maxn];
E a[maxn],b[maxn];
void fft(E *x,int f)
{
    for (int i=0;i<n;i++)
        if (i<r[i]) swap(x[i],x[r[i]]);
    for (int i=1;i<n;i<<=1)
    {
        E wn(cos(pi/i),f*sin(pi/i));
        for (int j=0;j<n;j+=(i<<1))
        {
            E w(1,0);
            for (int k=0;k<i;k++)
            {
                E r1,r2;
                r1=x[j+k];r2=w*x[i+j+k];
                x[j+k]=r1+r2;x[i+j+k]=r1-r2;
                w*=wn;
            }
        }
    }
    if (f==-1)
    {
        for (int i=0;i<n;i++)
            x[i]/=n;
    }
}
int main()
{
    scanf("%s",s);
    l1=strlen(s)-1;n=max(n,l1);
    for (int i=0;i<=l1;i++) a[i].real()=s[l1-i]-'0';
    scanf("%s",s);
    l2=strlen(s)-1;n=max(n,l2);
    for (int i=0;i<=l2;i++) b[i].real()=s[l2-i]-'0';
    m=2*n;
    for (n=1;n<=m;n<<=1) l++;
    for (int i=0;i<n;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    fft(a,1);fft(b,1);
    for (int i=0;i<n;i++) a[i]*=b[i];
    fft(a,-1);
    for (int i=0;i<=m;i++)
        c[i]=(int)(a[i].real()+0.1);
    int flag=0;
    for (int i=0;i<=m;i++)
    {
        if (c[i]>=10)
        {
            c[i+1]+=c[i]/10;
            c[i]%=10;
            if (i==m) m++;
        }
    }
    int p=m;while (c[p]==0) p--;
    for (int i=p;i>=0;i--) printf("%d",c[i]);
    printf("\n");
    return 0;
}