【HDU1402】A * B Problem Plus——FFT初步

44 篇文章 2 订阅
28 篇文章 0 订阅
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

看了好久的FFT今天终于水了一道题,看到一个大神的博客写的不错传送门,可以参考一下

#include<bits/stdc++.h>

using namespace std;
const int maxn = 1e5+100;
const double Pi = acos(-1.0);
struct Complex {
    double real,imag;
    Complex(){}
    Complex(double _r,double _i):real(_r),imag(_i){}
    Complex operator + (const Complex &a)const {
        return Complex(real+a.real,imag+a.imag);
    }
    Complex operator - (const Complex &a)const {
        return Complex(real-a.real,imag - a.imag);
    }
    Complex operator * (const Complex &a) const {
        return Complex(real*a.real-imag*a.imag,real*a.imag+imag*a.real);
    }
    void SetValue(double a,double b) {
        real = a; imag = b;
    }
    void Output() {
        printf("%f %f\n",real,imag);
    }
}a[2*maxn],b[2*maxn];
char str1[maxn],str2[maxn];
int len,len2,len1;
int res[maxn*2];
void Get(){
    len1 = strlen(str1);
    len2 = strlen(str2);
    int mlen = 2*max(len1,len2);
    len = 1; 
    while(len < mlen) len<<=1;
    for(int i = 0;i<len1;i++) a[i].SetValue(str1[len1-i-1]-'0',0);
    for(int i = 0;i<len2;i++) b[i].SetValue(str2[len2-i-1]-'0',0);
    for(int i = len1;i<len;i++) a[i].SetValue(0,0);
    for(int i = len2;i<len;i++) b[i].SetValue(0,0);   
}
void Rader(Complex y[]) {
    for(int i = 1,j = len>>1;i<len-1;i++) {
        if(i<j) swap(y[i],y[j]);
        int k = len>>1;
        while(j>=k) {
            j-=k;
            k>>=1;
        }
        if(j<k) j+=k;
    }

}
void FFT(Complex y[],int op) { 
    Rader(y);
    for(int h = 2;h<=len;h<<=1){
        Complex wn(cos(op*2*Pi/h),sin(op*2*Pi/h));
        for(int i = 0;i<len;i+=h) {
            Complex w(1,0);
            for(int j = i;j<i+h/2;j++){
                Complex u = y[j];
                Complex v = w*y[j+h/2];
                y[j] = u + v;
                y[j+h/2] = u - v;
                w = w*wn;
            }
        }
    }
    if(op == -1) {
        for(int i = 0;i<len;i++) y[i].real/=len;
    }
}
void Convolution() {
    FFT(a,1);
    FFT(b,1);
    for(int i = 0;i<len;i++) a[i] = a[i]*b[i];
    FFT(a,-1);
    for(int i = 0;i<len;i++) res[i] = (int)(a[i].real+0.5);
}
void Adopt() {
    for(int i = 0;i<len;i++) {
        res[i+1] += res[i]/10;
        res[i]%=10;
    }
    while(--len&&res[len] == 0); 
}
int main() {
    while(gets(str1) && gets(str2)){
        Get();
        Convolution();
        Adopt();
        for(int i = len;i>=0;i--) {
            putchar(res[i]+'0');
        }
        putchar('\n');
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值