1. 程式人生 > >CODEVS 3123 高精度練習之超大整數乘法

CODEVS 3123 高精度練習之超大整數乘法

題目描述 Description

給出兩個正整數A和B,計算A*B的值。保證A和B的位數不超過100000位。

輸入描述 Input Description

讀入兩個用空格隔開的正整數

輸出描述 Output Description

輸出A*B的值

樣例輸入 Sample Input

4 9

樣例輸出 Sample Output

36

資料範圍及提示 Data Size & Hint

兩個正整數的位數不超過100000位

分析

FFT板子題

程式碼

#include <bits/stdc++.h>

using namespace std
; const double _2pi = 3.1415926535 * 2; const int maxn = 10000000; int ans[maxn]; struct complexNumber { double real, image; }; complexNumber add(complexNumber a, complexNumber b) { return (complexNumber){a.real + b.real, a.image + b.image}; } complexNumber subtract(complexNumber a, complexNumber b) { return
(complexNumber){a.real - b.real, a.image - b.image}; } complexNumber multiply(complexNumber a, complexNumber b) { return (complexNumber){a.real * b.real - a.image * b.image, a.real * b.image + a.image * b.real}; } vector<complexNumber> A, B; void init() { ios::sync_with_stdio(false
); string n, m; cin >> n >> m; for(int i = n.length() - 1; i >= 0; i--) A.push_back((complexNumber){double(n[i] - '0'), 0.0}); for(int i = m.length() - 1; i >= 0; i--) B.push_back((complexNumber){double(m[i] - '0'), 0.0}); } vector<complexNumber> FFT(vector<complexNumber> X, bool inverse) { int n = X.size(); for(int i = 0, j = 0; i < n; i++) { if(i < j) swap(X[i], X[j]); int k = n; while(j & (k >>= 1)) j &= ~k; j |= k; } double theta = inverse == false ? _2pi : -_2pi; for(int s = 1; s <= log2((double)n); s++) { int m = pow(2, s); complexNumber omega_n = (complexNumber){cos(theta / double(m)), sin(theta / double(m))}; for(int k = 0; k < n; k += m) { complexNumber omega = (complexNumber){1.0, 0.0}; for(int j = 0; j < m / 2; j++) { complexNumber u = X[k + j], t = multiply(omega, X[k + j + m / 2]); X[k + j] = add(u, t); X[k + j + m / 2] = subtract(u, t); omega = multiply(omega, omega_n); } } } if(inverse == true) for(int i = 0; i < n; i++) X[i] = multiply(X[i], (complexNumber){1.0 / n, 0.0}); return X; } vector<complexNumber> Convolution(vector<complexNumber> A, vector<complexNumber> B) { vector<complexNumber> C; int s1 = A.size(), s2 = B.size(), n = 2; while(n < s1 + s2) n <<= 1; for(int i = s1; i < n; i++) A.push_back((complexNumber){0.0, 0.0}); vector<complexNumber> alpha = FFT(A, false); for(int i = s2; i < n; i++) B.push_back((complexNumber){0.0, 0.0}); vector<complexNumber> beta = FFT(B, false); for(int i = 0; i < n; i++) C.push_back(multiply(alpha[i], beta[i])); C = FFT(C, true); return C; } void solve() { vector<complexNumber> C = Convolution(A, B); int len = A.size() + B.size() - 1; for(int i = 0; i < len; i++) ans[i] = (int)round(C[i].real); for(int i = 0; i < len; i++) ans[i + 1] += ans[i] / 10, ans[i] %= 10; while(ans[len] == 0 && len > 0) len--; for(int i = len; i >= 0; i--) cout << ans[i]; } int main() { init(); solve(); return 0; }