如果有其它问题也请指出
#include <iostream>
#include <vector>
#include <algorithm>
#include <complex>
using namespace std;
typedef complex <double> Complex;
typedef vector <int> BigInt;
const double PI = acos(-1);
void FFT(vector <Complex> & poly, bool inverse) {
int n = poly.size();
if (n == 1) return;
vector <Complex> even(n / 2), odd(n / 2);
for (int i = 0, j = 0; i < n; i += 2, ++ j) {
even[j] = poly[i];
odd[j] = poly[i + 1];
}
FFT(even, inverse);
FFT(odd, inverse);
double angle = 2 * PI / n * (inverse ? -1 : 1);
Complex w(1), wn(cos(angle), sin(angle));
for (int i = 0; i < n / 2; ++ i) {
Complex temp = w * odd[i];
poly[i] = even[i] + temp;
poly[i + n / 2] = even[i] - temp;
w *= wn;
}
if (inverse) {
for (int i = 0; i < n; ++ i) {
poly[i] /= 2;
}
}
}
BigInt multiply(const BigInt& a, const BigInt& b) {
vector <Complex> fa(a.begin(), a.end()), fb(b.begin(), b.end());
int n = 1;
while (n < max(a.size(), b.size())) {
n <<= 1;
}
n <<= 1;
fa.resize(n);
fb.resize(n);
FFT(fa, false);
FFT(fb, false);
for (int i = 0; i < n; ++ i) {
fa[i] *= fb[i];
}
FFT(fa, true);
BigInt result(n);
for (int i = 0; i < n; ++ i) {
result[i] = static_cast <int> (fa[i].real() + 0.5);
}
int carry = 0;
for (int i = 0; i < n; ++ i) {
result[i] += carry;
carry = result[i] / 10;
result[i] %= 10;
}
while (result.size() > 1 && result.back() == 0) {
result.pop_back();
}
return result;
}
ostream& operator << (ostream& os, const BigInt& num) {
for (int i = num.size() - 1; i >= 0; -- i) {
os << num[i];
}
return os;
}
istream& operator >> (istream& is, BigInt& num) {
string str;
is >> str;
num.resize(str.length());
for (int i = 0; i < str.length(); ++ i) {
num[i] = str[str.length() - i - 1] - '0';
}
return is;
}
bool operator < (const BigInt& a, const BigInt& b) {
if (a.size() != b.size()) {
return a.size() < b.size();
}
for (int i = a.size() - 1; i >= 0; -- i) {
if (a[i] != b[i]) {
return a[i] < b[i];
}
}
return false;
}
bool operator > (const BigInt& a, const BigInt& b) {
return b < a;
}
bool operator <= (const BigInt& a, const BigInt& b) {
return !(a > b);
}
bool operator >= (const BigInt& a, const BigInt& b) {
return !(a < b);
}
bool operator != (const BigInt& a, const BigInt& b) {
return !(a == b);
}
bool operator == (const BigInt& a, const BigInt& b) {
if (a.size() != b.size()) {
return false;
}
for (int i = 0; i < a.size(); ++ i) {
if (a[i] != b[i]) {
return false;
}
}
return true;
}
BigInt operator + (const BigInt& a, const BigInt& b) {
BigInt result(max(a.size(), b.size()) + 1);
int carry = 0;
for (int i = 0; i < result.size(); ++ i) {
int val = (i < a.size() ? a[i] : 0) + (i < b.size() ? b[i] : 0) + carry;
result[i] = val % 10;
carry = val / 10;
}
while (result.size() > 1 && result.back() == 0) {
result.pop_back();
}
return result;
}
BigInt operator - (const BigInt& a, const BigInt& b) {
BigInt result = a;
int carry = 0;
for (int i = 0; i < b.size() || carry; ++ i) {
result[i] -= (i < b.size() ? b[i] : 0) + carry;
carry = result[i] < 0;
if (carry) {
result[i] += 10;
}
}
while (result.size() > 1 && result.back() == 0) {
result.pop_back();
}
return result;
}
BigInt operator * (const BigInt& a, const BigInt& b) {
return multiply(a, b);
}
BigInt operator / (const BigInt& a, const BigInt& b) {
BigInt result, dividend = a;
for (int i = a.size() - 1; i >= 0; -- i) {
result = result * BigInt(1, 0) + BigInt(1, dividend[i]);
while (result.size() > 1 && result.back() == 0) {
result.pop_back();
}
int quotient = 0;
int left = 0, right = 10;
while (left <= right) {
int mid = (left + right) / 2;
if (b * BigInt(1, mid) <= result) {
quotient = mid;
left = mid + 1;
} else {
right = mid - 1;
}
}
result = result - b * BigInt(1, quotient);
dividend[i] = quotient;
}
reverse(dividend.begin(), dividend.end());
while (dividend.size() > 1 && dividend.back() == 0) {
dividend.pop_back();
}
return dividend;
}
BigInt operator % (const BigInt& a, const BigInt& b) {
BigInt result = a;
for (int i = a.size() - 1; i >= 0; -- i) {
result = result * BigInt(1, 10) + BigInt(1, a[i]);
while (result.size() > 1 && result.back() == 0) {
result.pop_back();
}
int quotient = 0;
int left = 0, right = 10;
while (left <= right) {
int mid = (left + right) / 2;
if (b * BigInt(1, mid) <= result) {
quotient = mid;
left = mid + 1;
} else {
right = mid - 1;
}
}
result = result - b * BigInt(1, quotient);
}
while (result.size() > 1 && result.back() == 0) {
result.pop_back();
}
return result;
}
BigInt& operator += (BigInt& a, const BigInt& b) {
return a = a + b;
}
BigInt& operator -= (BigInt& a, const BigInt& b) {
return a = a - b;
}
BigInt& operator *= (BigInt& a, const BigInt& b) {
return a = a * b;
}
BigInt& operator /= (BigInt& a, const BigInt& b) {
return a = a / b;
}
BigInt& operator %= (BigInt& a, const BigInt& b) {
return a = a % b;
}
BigInt& operator ++ (BigInt& num) {
return num += BigInt(1, 1);
}
BigInt operator ++ (BigInt& num, int) {
BigInt temp = num;
++ num;
return temp;
}
BigInt& operator -- (BigInt& num) {
return num -= BigInt(1, 1);
}
BigInt operator -- (BigInt& num, int) {
BigInt temp = num;
-- num;
return temp;
}
bool operator ! (const BigInt& num) {
return num == BigInt(1, 0);
}