HDU 1402 A * B (FFT)
2016-04-15 17:59
274 查看
题意:
计算 A∗B (A,B 数字的长度 ≤50000)思路:
很裸的 FFT 入门题,最后的输出答案注意调整就OK了代码:
#include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #define PB push_back #define FT first #define SD second #define MP make_pair #define INF 0x3f3f3f3f using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> P; const int N = 2e5 + 10,MOD = 7+1e9; const double PI = acos(-1.0); struct Complex { double real, image; Complex(double _real, double _image) { real = _real; image = _image; } Complex(){} }; Complex operator + (const Complex &c1, const Complex &c2) { return Complex(c1.real + c2.real, c1.image + c2.image); } Complex operator - (const Complex &c1, const Complex &c2) { return Complex(c1.real - c2.real, c1.image - c2.image); } Complex operator * (const Complex &c1, const Complex &c2) { return Complex(c1.real*c2.real - c1.image*c2.image, c1.real*c2.image + c1.image*c2.real); } int rev(int id, int len) { int ret = 0; for(int i = 0; (1 << i) < len; i++) { ret <<= 1; if(id & (1 << i)) ret |= 1; } return ret; } Complex ret ; // 非递归形式,从递归的最后一层向上计算 void FFT(Complex* a, int n, int f) { for(int i = 0;i < n;++ i) ret[rev(i, n)] = a[i]; for(int s = 1; (1 << s) <= n;++ s) { int m = (1 << s); Complex wm = Complex(cos(f*2*PI/m), sin(f*2*PI/m)); for(int k = 0;k < n;k += m) { Complex w = Complex(1, 0); for(int j = 0;j < (m >> 1); ++j) { Complex t = w * ret[k + j + (m >> 1)]; Complex u = ret[k + j]; ret[k + j] = u + t; ret[k + j + (m >> 1)] = u - t; w = w * wm; } } } if(f == -1) for(int i = 0;i < n;++ i) ret[i].real /= n, ret[i].image /= n; for(int i = 0;i < n; ++i) a[i] = ret[i]; } char s1 , s2 ; Complex A , B ; int ans ; int main() { // freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scanf("%s %s", s1, s2)) { int sa = 0, sb = 0, l1 = strlen(s1), l2 = strlen(s2); while((1<<sa) < l1) sa ++; while((1<<sb) < l2) sb ++; int len = 1 << (max(sa, sb) + 1); for(int i = 0;i < len;i ++) { if(i < l1) A[i] = Complex(s1[l1 - i - 1] - '0', 0); else A[i] = Complex(0, 0); if(i < l2) B[i] = Complex(s2[l2 - i - 1] - '0', 0); else B[i] = Complex(0, 0); } FFT(A, len, 1); FFT(B, len, 1); for(int i = 0;i < len;i ++) A[i] = A[i] * B[i]; FFT(A, len, -1); for(int i = 0;i < len;i ++) ans[i] = int(A[i].real + 0.5); for(int i = 0;i < len - 1;i ++) ans[i+1] += ans[i] / 10, ans[i] %= 10; bool fg = 0; for(int i = len - 1;i >= 0;i --) { if(ans[i]) printf("%d", ans[i]), fg = 1; else if(fg || i == 0) printf("0"); } printf('\n'); } return 0; }