hdu 1402 A * B Problem Plus(FFT)

问题

hdu 1402 A * B Problem Plus - http://acm.hdu.edu.cn/showproblem.php?pid=1402

分析

  • fft

代码

#include<bits/stdc++.h>
using namespace std;
typedef complex<double> cd;
typedef long long ll;
const double DFT = 2.0, IDFT = -2.0, PI = acos(-1);
const int MXN = 5e4+10, MXL = MXN << 2;
cd p1[MXL], p2[MXL];
int n, r[MXL], ans[MXN<<1];
char a[MXN], b[MXN];
void fft(cd p[], int len, double mode){
    for(int i = 0; i < len; ++i) if(i < r[i]) swap(p[i], p[r[i]]);
    for(int i = 2; i <= len; i <<= 1){
        cd wn(cos(mode*PI/i), sin(mode*PI/i));
        for(int j = 0; j < len; j += i){
            cd w(1.0, 0.0);
            for(int k = j; k < j+(i>>1); ++k, w *= wn){
                cd l = p[k], r = w*p[k+(i>>1)];
                p[k] = l + r, p[k+(i>>1)] = l - r;
            }
        }
    }
    if(mode == DFT) return;
    for(int i = 0; i <= len; ++i) p[i] /= len;
}
int getnum(char c[], cd p[]){
    int len = strlen(c)-1;
    for(int i = 0; i <= len; ++i) p[len-i] = c[i] - '0';
    return len;
}
int main(){
    int t, lim, bit;
    while(scanf("%s%s", a, b) == 2){
        for(int i = 0; i < MXL; ++i) p1[i] = p2[i] = 0;
        lim = getnum(a, p1), lim += getnum(b, p2);
        bit = 1;
        while(lim >>= 1) ++bit;
        lim = 1 << bit;
        for(int i = 0; i < lim; ++i) r[i] = (r[i>>1]>>1)|((i&1)<<(bit-1));
        fft(p1, lim, DFT), fft(p2, lim, DFT);
        for(int i = 0; i < lim; ++i) p1[i] *= p2[i];
        fft(p1, lim, IDFT);
        for(int i = 0; i < (MXN<<1); ++i) ans[i] = (int)(p1[i].real()+0.5);
        for(int i = 0; i < (MXN<<1)-1; ++i) ans[i+1] += ans[i]/10, ans[i] %= 10;
        int i = (MXN<<1)-1;
        while(ans[i] == 0 && i >= 1) --i;
        while(i >= 0) printf("%d", ans[i--]);
        printf("\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jpphy0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值