[HDU 1402]A * B Problem Plus(其實是FFT模板)

Problem Description


Calculate A * B.

Solution


本來是想交一下bzoj2179的,打開之後發現是權限題= =
一怒之下找到了高精度乘…很好

感覺對FFT的理解並不完全,有時間再看看算導吧,先苟延殘喘地打個板子湊合用= =

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cstdlib>
#include<cmath>
#define PI acos(-1.0)
using namespace std;
struct cp
{
    double r,i;
    cp(double r=0,double i=0):r(r),i(i){}
    cp operator + (const cp& x){
        return cp(r+x.r,i+x.i);
    }
    cp operator - (const cp& x){
        return cp(r-x.r,i-x.i);
    }
    cp operator * (const cp& x){
        return cp(r*x.r-i*x.i,r*x.i+i*x.r);
    }
};
char s1[200005],s2[200005];
int res[200005];
cp a[200005],b[200005];
void brc(cp *x,int l)
{
    int j=l/2;
    for(int i=1;i<l-1;i++)
    {
        if(i<j)swap(x[i],x[j]);
        int k=l/2;
        while(j>=k)
        {
            j-=k;//遇到1變成0,遇到0則退出並把這一位變成1 
            k>>=1;
        }
        if(j<k)j+=k;
    }
}
void fft(cp *x,int l,int on)
{
    brc(x,l);
    for(int h=2;h<=l;h<<=1)
    {
        cp wn(cos(on*2*PI/h),sin(on*2*PI/h));
        for(int j=0;j<l;j+=h)
        {
            cp w(1,0);
            for(int k=j;k<j+h/2;k++)
            {
                cp u=x[k];
                cp t=w*x[k+h/2];
                x[k]=u+t;
                x[k+h/2]=u-t;
                w=w*wn;
            }
        }
    }
    if(on==-1)for(int i=0;i<l;i++)x[i].r/=l;
}
int main()
{
    while(~scanf("%s%s",s1,s2))
    {
        memset(res,0,sizeof(res));
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        int l1,l2,l=1;
        l1=strlen(s1);l2=strlen(s2);
        while(l<l1*2||l<l2*2)l<<=1;
        for(int i=0;i<l1;i++)
        {
            a[l1-i-1].r=s1[i]-'0';
            a[l1-i-1].i=0;
        }
        for(int i=0;i<l2;i++)
        {
            b[l2-i-1].r=s2[i]-'0';
            b[l2-i-1].i=0;
        }
        fft(a,l,1);
        fft(b,l,1);
        for(int i=0;i<l;i++)
        a[i]=a[i]*b[i];
        fft(a,l,-1);
        for(int i=0;i<l;i++)
        res[i]=a[i].r+0.5;
        l=l1+l2-1;
        for(int i=0;i<l;i++)
        {
            res[i+1]+=res[i]/10;
            res[i]%=10;
        }
        while(res[l]<=0&&l>0)l--;
        while(l>=0)
        {
            printf("%d",res[l]);
            l--;
        }
        printf("\n");
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章