CODEVS 3123 高精度練習之超大整數乘法
阿新 • • 發佈:2019-02-09
題目描述 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;
}