HDU1402 A * B Problem Plus (FFT)

OJ HDU 专栏收录该内容
1 篇文章 0 订阅

题目

HDU1402

思路

把数字转化成 ∑ a i ∗ 1 0 i \sum a_i*10^i ai10i的形式,然后用 F F T FFT FFT

代码

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <set>
#include <complex>

using namespace std;

typedef long long ll;
typedef double db;
typedef complex<double> cp;

const int maxn=(int)2e5+9;
const db pi=acos(-1);

#define sh(x) cout<<#x<<" is "<<x<<endl;

int rev[maxn];
cp an[maxn],bn[maxn];
int c[maxn];
char as[maxn],bs[maxn];

void fft(cp* a,int n,int inv){
    int bit=0;
    while((1<<bit)<n)bit++;
    for(int i=0;i<n;i++){
        rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
        if(i<rev[i])swap(a[i],a[rev[i]]);
    }
    for(int i=1;i<=bit;i++){
        int len=1<<i;
        cp w1(cos(2*pi/len),inv*sin(2*pi/len));
        for(int j=0;j<n;j+=len){
            cp w(1,0);
            for(int k=0;k<(len>>1);k++){
                cp re=a[j+k];
                cp im=w*a[j+k+(len>>1)];
                a[j+k]=re+im;
                a[j+k+(len>>1)]=re-im;
                w*=w1;
            }
        }
    }
}

int main(){
    while(scanf("%s%s",as,bs)==2){
        int l1=strlen(as);
        int l2=strlen(bs);
        for(int i=0;as[i];i++)an[l1-1-i]=as[i]-'0';
        for(int i=0;bs[i];i++)bn[l2-1-i]=bs[i]-'0';
        int m=l1+l2,n;
        for(n=1;n<m;n<<=1);
        for(int i=l1;i<n;i++)an[i]=0;
        for(int i=l2;i<n;i++)bn[i]=0;
        fft(an,n,1);
        fft(bn,n,1);
        for(int i=0;i<n;i++)an[i]*=bn[i];
        fft(an,n,-1);
        memset(c,0,sizeof(c));
        int t=0;
        for(int i=0;i<n;i++){
            c[i]+=floor(an[i].real()/n+0.5);
            c[i+1]+=c[i]/10;
            c[i]%=10;
            if(c[i])t=i;
        }
        for(;t>=0;t--){
            printf("%c",c[t]+'0');
        }
        printf("\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值