hdu 1402 A * B Problem Plus FFT模板

来贴模板啦。。NTT的以后再说=。=

#include<cstdio>
#include<complex>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;

const int N = 1<<18;
const double PI = acos(-1.0);

struct Complex{
    double x, y;
    Complex(double xx = 0, double yy = 0){ x = xx, y = yy; }
    friend Complex operator + (const Complex &a, const Complex &b){
        return Complex(a.x+b.x, a.y+b.y);
    }
    friend Complex operator - (const Complex &a, const Complex &b){
        return Complex(a.x-b.x, a.y-b.y);
    }
    friend Complex operator * (const Complex &a, const Complex &b){
        return Complex(a.x*b.x-a.y*b.y, a.y*b.x+b.y*a.x);
    }
};
typedef Complex CD;
//typedef complex<double> CD;

void FFT(CD* a, int n, int oper){
    for (int i = 1, j = 0; i < n; i++){
        for (int s = n; j^=s>>=1, ~j&s;);
        if (i < j) swap(a[i], a[j]);
    }
    for (int m = 1; m < n; m <<= 1){
        int m2 = m<<1;
        double p = PI/m*oper;
        CD w = CD(cos(p), sin(p));
        for (int i = 0; i < n; i += m2){
            CD unit = 1;
            for (int j = 0; j < m; j++){
                CD &x = a[i+j+m], &y = a[i+j], t = unit*x;
                x = y-t;
                y = y+t;
                //unit *= w;
                unit = unit * w;
            }
        }
    }
    //if (oper == -1) for (int i = 0; i < n; i++) a[i] /= n;
    if (oper == -1) for (int i = 0; i < n; i++) a[i].x /= n;
}

void Polynomial_Mul(int* A, int la, int* B, int lb, int* C, int& lc){
    int n = 1; while(n < la + lb) n <<= 1;
    static CD a[N], b[N];
    for (int i = 0; i < n; i++){
        a[i] = i<la? A[i]: 0;
        b[i] = i<lb? B[i]: 0;
    }
    FFT(a, n, 1);
    FFT(b, n, 1);
    //for (int i = 0; i < n; i++) a[i] *= b[i];
    for (int i = 0; i < n; i++) a[i] = a[i] * b[i];
    FFT(a, n, -1);
    lc = la + lb - 1;
    //for (int i = 0; i < lc; i++) C[i] = (int)(a[i].real() + 0.5);
    for (int i = 0; i < lc; i++) C[i] = (int)(a[i].x + 0.5);
}

const int maxn = 50100;
char s1[maxn], s2[maxn];
int A[maxn<<1], B[maxn];
int main()
{
    while(scanf("%s %s", s1, s2) == 2){
        int la = strlen(s1), lb = strlen(s2);
        for (int i = 0; i < la; i++) A[la-1-i] = s1[i] - '0';
        for (int i = 0; i < lb; i++) B[lb-1-i] = s2[i] - '0';
        Polynomial_Mul(A, la, B, lb, A, la);
        A[la] = 0;
        for (int i = 0; i < la; i++) if (A[i] > 9){ A[i+1] += A[i] / 10; A[i] %= 10; }
        bool zero = true;
        for (int i = la; i >= 0; i--){
            if (zero && !A[i]) continue;
            zero = false;
            printf("%c", A[i] + '0');
        }
        if (zero) puts("0");
        else puts("");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值