HDU 1402 FFT

code :

#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
typedef double ld;

const ld PI = acos(-1.0);
const int N = 50010;
const int maxN = 150010;
char A[maxN], B[maxN];

inline int max(int a, int b){return a >= b ? a : b;}

struct Complex{/**复数*/
    ld real, vir;
    Complex(){}
    Complex(ld r, ld v):real(r), vir(v){}
    Complex operator + (const Complex &rhs) const{
        return Complex(real + rhs.real, vir + rhs.vir);
    }
    Complex operator - (const Complex &rhs) const{
        return Complex(real - rhs.real, vir - rhs.vir);
    }
    Complex operator * (const Complex &rhs) const{
        return Complex(real * rhs.real - vir * rhs.vir, real * rhs.vir + vir * rhs.real);
    }
}fa[maxN], fb[maxN], tmp[maxN];
int ans[maxN];

void FFT(Complex t[], int len, int f){/**递归写法*/
    if(len == 1) return;
    //f = -f;
    Complex wn(cos(2 * PI / len * f), sin(2 * PI / len * f));
    for(int i = 0; i < len / 2; ++i) tmp[i] = t[i * 2], tmp[len / 2 + i] = t[i * 2 + 1];
    for(int i = 0; i < len; ++i) t[i] = tmp[i];
    FFT(t, len / 2, f);
    FFT(t + len / 2, len / 2, f);
    Complex w(1, 0);
    for(int i = 0; i < len / 2; ++i){
        Complex u = t[i];
        Complex v = w * t[i + len / 2];
        t[i] = u + v;
        t[i + len / 2] = u - v;
        w = w * wn;
    }
}
int main(){
    while(~scanf("%s%s", A, B)){
        memset(ans, 0, sizeof ans);
        int lena = strlen(A), lenb = strlen(B);
        int lent = max(lena, lenb);
        lent <<= 1;
        int len = 1;
        while(len < lent) len <<= 1;/**2的幂*/
       // printf("%d\n", len);
        for(int i = 0; i < len; ++i){
            if(i < lena) fa[i] = Complex(A[lena - i - 1] - '0', 0);
            else fa[i] = Complex(0, 0);
            if(i < lenb) fb[i] = Complex(B[lenb - i - 1] - '0', 0);
            else fb[i] = Complex(0, 0);
        }
        FFT(fa, len, 1);/**系数到点值*/
        FFT(fb, len, 1);
        for(int i = 0; i < len; ++i) fa[i] = fa[i] * fb[i];
        FFT(fa, len, -1);
        for(int i = 0; i < len; ++i){
            fa[i].real /= len;
            fa[i].vir /= len;
        }/**点值到系数*/
        for(int i = 0; i < len; ++i) ans[i] = (int)(fa[i].real + 0.5);
        for(int i = 0; i < len; ++i){
            ans[i + 1] += ans[i] / 10;
            ans[i] %= 10;
        }
        int id = lena + lenb - 1;
        while(ans[id] == 0 && id) --id;/**注意0数据*/
        for(int i = id; i >= 0; --i) printf("%d", ans[i]);
        puts("");
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值