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;
}
發佈了308 篇原創文章 · 獲贊 146 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章