hdu 1402 A * B Problem Plus (FFT模板)

A * B Problem Plus

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

 FFT的模板题。我们把数字的每一位看成i*(x^j),当我们把x取成10的时候我们就得到了这个大整数

#include <bits/stdc++.h>

using namespace std;
const int maxn = 50000+500;
const double pi = acos(-1.0);
const double PI = acos(-1.0);
#define fft FFT
#define r real
struct Complex
{
    double r,i;
    Complex(double _r,double _i):r(_r),i(_i){}
    Complex(){}
    Complex operator +(const Complex &b)
    {
        return Complex(r+b.r,i+b.i);
    }
    Complex operator -(const Complex &b)
    {
        return Complex(r-b.r,i-b.i);
    }
    Complex operator *(const Complex &b)
    {
        return Complex(r*b.r-i*b.i,r*b.i+i*b.r);
    }
};
void change(Complex y[],int len)
{
    int i,j,k;
    for(i = 1, j = len/2;i < len-1;i++)
    {
        if(i < j)swap(y[i],y[j]);
        k = len/2;
        while( j >= k)
        {
            j -= k;
            k /= 2;
        }
        if(j < k)j += k;
    }
}
void fft(Complex y[],int len,int on)
{
    change(y,len);
    for(int h = 2;h <= len;h <<= 1)
    {
        Complex wn(cos(-on*2*pi/h),sin(-on*2*pi/h));
        for(int j = 0;j < len;j += h)
        {
            Complex w(1,0);
            for(int k = j;k < j+h/2;k++)
            {
                Complex u = y[k];
                Complex t = w*y[k+h/2];
                y[k] = u+t;
                y[k+h/2] = u-t;
                w = w*wn;
            }
        }
    }
    if(on == -1)
        for(int i = 0;i < len;i++)
            y[i].r /= len;
}
char numA[maxn],numB[maxn];
Complex a[maxn*2],b[maxn*2];
int ans[maxn*2];
int main()
{
    //freopen("de.txt","r",stdin);
    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] = Complex(numA[lenA-i-1]-'0',0);
            else a[i] = Complex(0,0);
            if (i<lenB) b[i] = Complex(numB[lenB-i-1]-'0',0);
            else b[i] = Complex(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);//DFT逆变换回去
        for (int i=0;i<len;++i)
            ans[i] = (int)(a[i].r+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");
        }
        printf("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/agenthtb/p/7309299.html