/*
bigint()
bigint(long long)
bigint(bigint)
bigint(char*)
bigint(string)
+, +=, ++
-, -=, --
*, *=
/, /=
<<, <<=
==, !=
<, <=
>, >=
-
!
abs(bigint), bigint.abs()
pow(bigint, unsigned), bigint.pow(unsigned)
root(bigint, unsigned), bigint.root(unsigned)
sqrt(bigint), bigint.sqrt()
bigint.read(default = stdin)
bigint.write(default = stdout)
istream>>bigint
ostream<<bigint
enoughMemory() : optimize division and modulo
*/
#include <iostream> #ifndef BIGINT
#define BIGINT 1 #include <istream>
#include <ostream>
#include <string>
#include <vector>
#include <complex>
#include <algorithm>
#include <utility>
#include <cstring>
#include <cstdio>
using namespace std; static const unsigned base = 10000, length = 4;
static bool __enoughMemory = false; typedef vector<int> vi;
typedef vector<int>::iterator viit;
typedef vector<int>::const_iterator vicit;
typedef vector<int>::reverse_iterator virit;
typedef vector<int>::const_reverse_iterator vicrit;
typedef complex<double> comp;
typedef vector<comp> vc;
typedef vector<comp>::iterator vcit; class Bigint {
public :
Bigint();
template<typename _Tp> Bigint(_Tp);
Bigint(const Bigint&);
Bigint(const char*);
Bigint(const string&); bool& neg();
const bool& neg() const;
vi& num();
const vi& num() const; bool operator==(const Bigint&) const;
bool operator!=(const Bigint&) const;
bool operator<(const Bigint&) const;
bool operator<=(const Bigint&) const;
bool operator>(const Bigint&) const;
bool operator>=(const Bigint&) const; Bigint& operator+=(const Bigint&);
Bigint& operator-=(const Bigint&);
Bigint& operator*=(const Bigint&);
Bigint& operator/=(const Bigint&);
Bigint& operator%=(const Bigint&);
Bigint& operator<<=(const unsigned&);
Bigint& operator>>=(const unsigned&); Bigint& operator++();
Bigint& operator--();
Bigint operator-() const;
bool operator!() const; int compare(const Bigint&) const;
bool equal(const Bigint&) const;
bool less(const Bigint&) const;
bool lessOrEqual(const Bigint&) const;
bool greater(const Bigint&) const;
bool greaterOrEqual(const Bigint&) const; Bigint& abs();
Bigint& pow(unsigned);
Bigint& root(const unsigned&);
Bigint& sqrt();
void multiply10(const unsigned&);
void divide2(); void add(const Bigint&);
void subtract(const Bigint&);
void multiply(const Bigint&);
void multiplySlow(const Bigint&);
void multiplyFast(const Bigint&, const int&, const int&);
pair<vi, vi> divide(const Bigint&); Bigint& read(FILE*);
const Bigint& write(FILE*) const; private :
bool _m_neg;
vi _m_num; void adjust();
comp exp(const double&);
void bitrev(const vcit&, const int&, const int&, const int&, const int&);
void fft(vc&, const int&, const int&, const bool&); void divideByZero();
void imaginaryNumberUnsupported();
void error(const string&);
}; //pre-declaration
Bigint abs(const Bigint&);
Bigint pow(const Bigint&, const unsigned&);
Bigint root(const Bigint&, const unsigned&);
Bigint sqrt(const Bigint&);
istream& operator>>(istream&, Bigint&);
ostream& operator<<(ostream&, const Bigint&);
void enoughMemory(); //operator
inline Bigint operator+(const Bigint& __x, const Bigint& __y) {
return Bigint(__x) += __y;
}
inline Bigint operator-(const Bigint& __x, const Bigint& __y) {
return Bigint(__x) -= __y;
}
inline Bigint operator*(const Bigint& __x, const Bigint& __y) {
return Bigint(__x) *= __y;
}
inline Bigint operator/(const Bigint& __x, const Bigint& __y) {
return Bigint(__x) /= __y;
}
inline Bigint operator%(const Bigint& __x, const Bigint& __y) {
return Bigint(__x) %= __y;
}
template<typename _Tp> inline Bigint operator<<(const Bigint& __x, const _Tp& __y) {
return Bigint(__x) <<= __y;
}
template<typename _Tp> inline Bigint operator>>(const Bigint& __x, const _Tp& __y) {
return Bigint(__x) >>= __y;
} //public //constructor
inline Bigint::Bigint() {
neg() = false;
num().clear();
num().push_back(0);
}
template<typename _Tp> inline Bigint::Bigint(_Tp __t) {
if (__t < 0) neg() = true, __t = -__t;
else neg() = false;
num().clear();
while (__t >= base) {
num().push_back(__t % base);
__t /= base;
}
num().push_back(__t);
}
inline Bigint::Bigint(const Bigint& __t) {
*this = __t;
}
inline Bigint::Bigint(const char* __c) {
while (*__c) {
if (*__c == '-' || *__c == '+' || '0' <= *__c && *__c <= '9')
break;
++__c;
}
if (*__c == '-') ++__c, neg() = true;
else {
neg() = false;
if (*__c == '+') ++__c;
}
int __n = strlen(__c);
num().clear();
if (__n == 0) {
neg() = false;
num().push_back(0);
return ;
}
const char* __t = __c + __n;
while (__c + 1 != __t && *__c == '0') ++__c;
int __x = 0, __y = 1, __z = 0;
while (__t-- != __c) {
if (__z == 4) {
num().push_back(__x);
__x = 0, __y = 1, __z = 0;
}
__x += (*__t - '0') * __y;
__y = (__y << 3) + (__y << 1);
++__z;
}
num().push_back(__x);
}
inline Bigint::Bigint(const string& __s) {
string::const_iterator i = __s.begin();
string::const_iterator j = __s.end();
while (i != j) {
if (*i == '-' || *i == '+' || '0' <= *i && *i <= '9')
break;
++i;
}
if (i != j) {
if (*i == '-') ++i, neg() = true;
else {
neg() = false;
if (*i == '+') ++i;
}
}
int __n = j - i;
if (__n == 0) {
neg() = false;
num().push_back(0);
return ;
}
while (i + 1 != j && *i == '0') ++i;
int __x = 0, __y = 1, __z = 0;
while (j-- != i) {
if (__z == 4) {
num().push_back(__x);
__x = 0, __y = 1, __z = 0;
}
__x += (*j - '0') * __y;
__y = (__y << 3) + (__y << 1);
++__z;
}
num().push_back(__x);
} inline bool& Bigint::neg() {
return _m_neg;
}
inline const bool& Bigint::neg() const {
return _m_neg;
}
inline vi& Bigint::num() {
return _m_num;
}
inline const vi& Bigint::num() const {
return _m_num;
} //logical operator
inline bool Bigint::operator==(const Bigint& __t) const {
return neg() == __t.neg() && equal(__t);
}
inline bool Bigint::operator!=(const Bigint& __t) const {
return neg() != __t.neg() || !equal(__t);
}
inline bool Bigint::operator<(const Bigint& __t) const {
if (neg() != __t.neg()) return neg();
if (neg()) return greater(__t);
return less(__t);
}
inline bool Bigint::operator<=(const Bigint& __t) const {
if (neg() != __t.neg()) return neg();
if (neg()) return greaterOrEqual(__t);
return lessOrEqual(__t);
}
inline bool Bigint::operator>(const Bigint& __t) const {
if (neg() != __t.neg()) return __t.neg();
if (neg()) return less(__t);
return greater(__t);
}
inline bool Bigint::operator>=(const Bigint& __t) const {
if (neg() != __t.neg()) return __t.neg();
if (neg()) return lessOrEqual(__t);
return greaterOrEqual(__t);
} //arithmetic operators
inline Bigint& Bigint::operator+=(const Bigint& __t) {
if (neg() == __t.neg()) add(__t);
else {
int __x = compare(__t);
if (__x == 0) *this = Bigint();
else if (__x == -1) {
Bigint __y = *this;
*this = __t;
subtract(__y);
}
else subtract(__t);
}
return *this;
}
inline Bigint& Bigint::operator-=(const Bigint& __t) {
return *this += (-__t);
}
inline Bigint& Bigint::operator*=(const Bigint& __t) {
if (*this != 0 && __t != 0) {
neg() = neg() != __t.neg();
multiply(__t);
}
else *this = Bigint();
return *this;
}
inline Bigint& Bigint::operator/=(const Bigint& __t) {
if (__t == 0) divideByZero();
if (less(__t)) *this = Bigint();
else {
neg() = neg() != __t.neg();
num() = divide(__t).first;
adjust();
}
return *this;
}
inline Bigint& Bigint::operator%=(const Bigint& __t) {
if (__t == 0) divideByZero();
num() = divide(__t).second;
adjust();
if (num().size() == 1 && !*num().rbegin()) neg() = false;
return *this;
}
inline Bigint& Bigint::operator<<=(const unsigned& __y) {
return *this *= Bigint(2).pow(__y);
}
inline Bigint& Bigint::operator>>=(const unsigned& __y) {
for (unsigned i = 0 ; i < __y ; ++i) divide2();
return *this;
} //self operator
inline Bigint& Bigint::operator++() {
return *this += 1;
}
inline Bigint& Bigint::operator--() {
return *this -= 1;
}
inline Bigint Bigint::operator-() const {
Bigint __t = *this;
if (__t != 0) __t.neg() ^= true;
return __t;
}
inline bool Bigint::operator!() const {
return *this == 0;
} //comparator
inline int Bigint::compare(const Bigint& __t) const {
if (num().size() < __t.num().size()) return -1;
else if (num().size() > __t.num().size()) return 1;
vicrit i = num().rbegin();
vicrit j = __t.num().rbegin();
while (i != num().rend()) {
if (*i < *j) return -1;
else if (*i > *j) return 1;
++i, ++j;
}
return 0;
}
inline bool Bigint::equal(const Bigint& __t) const {
return compare(__t) == 0;
}
inline bool Bigint::less(const Bigint& __t) const {
return compare(__t) == -1;
}
inline bool Bigint::lessOrEqual(const Bigint& __t) const {
int __r = compare(__t);
return __r == -1 || __r == 0;
}
inline bool Bigint::greater(const Bigint& __t) const {
return compare(__t) == 1;
}
inline bool Bigint::greaterOrEqual(const Bigint& __t) const {
int __r = compare(__t);
return __r == 1 || __r == 0;
} //math
inline Bigint& Bigint::abs() {
if (neg()) neg() = false;
return *this;
}
inline Bigint& Bigint::pow(unsigned __y) {
Bigint __x = *this;
*this = 1;
while (__y) {
if (__y & 1) *this *= __x;
__x *= __x;
__y >>= 1;
}
return *this;
}
inline Bigint& Bigint::root(const unsigned& __y = 2) {
if (!__y) divideByZero();
if (*this == 0 || __y == 1) return *this;
bool __n = neg();
if (__n)
if (__y & 1) neg() = false;
else imaginaryNumberUnsupported();
const double log2_10 = 3.3219280948873623478703194294893901758648313930245806;
size_t __s = num().size();
if (double(__s << 2) * log2_10 < __y) return *this = 1;
__s = __s / __y + (__s % __y ? 1 : 0);
int __l, __r, __m;
Bigint __a = *this, __b, __c;
num().clear();
for (int i = __s - 1 ; i >= 0 ; --i) {
__l = 1, __r = base - 1;
while (__l <= __r) {
__m = __l + __r >> 1;
__b = *this;
__b.num().insert(__b.num().begin(), __m);
__b.pow(__y);
__b.multiply10(i * __y << 2);
if (__b <= __a) __l = __m + 1;
else __r = __m - 1;
}
num().insert(num().begin(), __r);
}
neg() = __n;
return *this;
}
inline Bigint& Bigint::sqrt() {
root();
return *this;
}
inline void Bigint::multiply10(const unsigned& __t) {
if (!__t) return ;
size_t __s = num().size();
size_t __r = (__t >> 2) + (__t & 3 ? 1 : 0);
int __x = 0, __y, __z, __a, __b;
if ((__t & 3) == 0) __a = 1, __b = 10000;
else if ((__t & 3) == 1) __a = 1000, __b = 10;
else if ((__t & 3) == 2) __a = 100, __b = 100;
else if ((__t & 3) == 3) __a = 10, __b = 1000;
num().resize(__s + __r);
virit i = num().rbegin();
virit j = i + __r;
while (i != num().rbegin() + __s) {
__y = *j++;
__z = __y / __a;
__x += __z;
*i++ = __x;
__x = (__y - __z * __a) * __b;
}
*i++ = __x;
fill(i, num().rend(), 0);
adjust();
}
inline void Bigint::divide2() {
int __t = 0;
for (virit i = num().rbegin() ; i != num().rend() ; ++i) {
__t = (__t & 1 ? base : 0) + *i;
*i = __t >> 1;
}
adjust();
} //+, -, *, /
inline void Bigint::add(const Bigint& __t) {
if (num().size() < __t.num().size())
num().resize(__t.num().size());
viit i = num().begin();
vicit j = __t.num().begin();
while (i != num().end() && j != __t.num().end())
*i++ += *j++;
for (i = num().begin() ; i + 1 != num().end() ; ++i)
if (*i >= base) {
*i -= base;
++*(i + 1);
}
if (*i >= base) {
*i -= base;
num().push_back(1);
}
}
inline void Bigint::subtract(const Bigint& __t) {
viit i = num().begin();
vicit j = __t.num().begin();
while (j != __t.num().end())
*i++ -= *j++;
for (i = num().begin() ; i + 1 != num().end() ; ++i)
if (*i < 0) {
*i += base;
--*(i + 1);
}
adjust();
}
inline void Bigint::multiply(const Bigint& __t) {
int __n = max(num().size(), __t.num().size());
int __l = 0;
while ((1 << __l) < __n) ++__l;
__n = 1 << ++__l;
if ((long long)num().size() * __t.num().size() <= (long long)__n * __l * 20)
multiplySlow(__t);
else
multiplyFast(__t, __n, __l);
adjust();
}
inline void Bigint::multiplySlow(const Bigint& __t) {
int __n = num().size() + __t.num().size(), i, j, k;
vi __x, __y;
if (__t.num().size() * 4 < num().size())
__x = __t.num(), __y = num();
else
__x = num(), __y = __t.num();
num().clear();
num().resize(__n);
for (i = 0 ; i < __x.size() ; ++i) {
k = __x[i];
for (j = 0 ; j < __y.size() ; ++j)
num()[i + j] += k * __y[j];
k = i + 1 + __y.size();
for (j = 0 ; j < k ; ++j) {
num()[j + 1] += num()[j] / base;
num()[j] %= base;
}
}
}
inline void Bigint::multiplyFast(const Bigint& __t, const int& __n, const int& __l) {
vc a, b;
a.reserve(__n);
b.reserve(__n);
for (viit i = num().begin() ; i != num().end() ; ++i)
a.push_back(comp(*i, 0));
for (vicit i = __t.num().begin() ; i != __t.num().end() ; ++i)
b.push_back(comp(*i, 0));
a.resize(__n);
b.resize(__n);
fft(a, __l, __n, true);
fft(b, __l, __n, true);
vcit i = a.begin(), j = b.begin();
while (i != a.end()) *i++ *= *j++;
fft(a, __l, __n, false);
long long __x = 0;
num().resize(__n);
i = a.begin();
viit k = num().begin();
while (i != a.end()) {
__x = (long long)(i++ ->real() / __n + 0.5) + __x / base;
*k++ = __x % base;
}
}
inline pair<vi, vi> Bigint::divide(const Bigint& __t) {
int __l, __r, __m, __n = num().size() - __t.num().size() + 1;
Bigint __x = *this, __y = __t, __z;
vi __v;
__v.resize(__n);
if (__enoughMemory) {
Bigint __p[10];
for (__m = 0 ; __m < 10 ; ++__m) __p[__m] = __m * __y;
for (int i = __n - 1 ; i >= 0 ; --i) {
int k = 0;
for (int j = 3 + (i << 2) ; j >= (i << 2) ; --j) {
__l = 1, __r = 9;
while (__l <= __r) {
__m = __l + __r >> 1;
__z = __p[__m];
__z.multiply10(j);
if (__z.greater(__x)) __r = __m - 1;
else __l = __m + 1;
}
k = (k << 3) + (k << 1) + __r;
__z = __p[__r];
__z.multiply10(j);
__x.subtract(__z);
}
__v[i] = k;
}
}
else {
for (int i = __n - 1 ; i >= 0 ; --i) {
__l = 1, __r = base - 1;
while (__l <= __r) {
__m = __l + __r >> 1;
__z = __m * __y;
__z.multiply10(i << 2);
if (__z.greater(__x)) __r = __m - 1;
else __l = __m + 1;
}
__v[i] = __r;
__z = __r * __y;
__z.multiply10(i << 2);
__x.subtract(__z);
}
}
return make_pair(__v, __x.num());
} //io
inline Bigint& Bigint::read(FILE *in = stdin) {
string __s = "";
char __c = fgetc(in);
while (true) {
if (__c == '-' || __c == '+' || '0' <= __c && __c <= '9' || __c == EOF)
break;
__c = fgetc(in);
}
while (true) {
__s += __c;
__c = fgetc(in);
if (__c < '0' || __c > '9') break;
}
return *this = Bigint(__s.c_str());
}
inline const Bigint& Bigint::write(FILE *out = stdout) const {
vicrit i = num().rbegin();
if (neg()) fprintf(out, "-");
fprintf(out, "%d", *i++);
while (i != num().rend()) fprintf(out, "%04d", *i++);
return *this;
} //private //other
inline void Bigint::adjust() {
virit i = num().rbegin();
while (i + 1 != num().rend()) {
if (*i) break;
++i;
}
num().erase(i.base(), num().end());
}
inline comp Bigint::exp(const double& u) {
return comp(cos(u), sin(u));
}
inline void Bigint::bitrev(const vcit& i, const int& __l, const int& __p, const int& __x, const int& __y) {
if (__p == 0) {
if (__x < __y) swap(*(i + __x), *(i + __y));
return ;
}
bitrev(i, __l, __p - 1, __x << 1, __y);
bitrev(i, __l, __p - 1, __x << 1 | 1, __y | (1 << __l - __p));
}
inline void Bigint::fft(vc& __a, const int& __l, const int& __n, const bool& __r) {
const double __p = 3.141592653589793238462643383279;
bitrev(__a.begin(), __l, __l, 0, 0);
for (int i = 1 ; i <= __l ; ++i) {
int __m = 1 << i;
comp wm = exp((__r ? -2 : 2) * __p / __m);
for (int k = 0 ; k < __n ; k += __m) {
comp w = 1;
for (int j = 0 ; j < __m / 2 ; ++j) {
comp t = w * __a[k + j + __m / 2];
comp u = __a[k + j];
__a[k + j] = u + t;
__a[k + j + __m / 2] = u - t;
w *= wm;
}
}
}
} //error
inline void Bigint::divideByZero() {
error("divide by zero");
}
inline void Bigint::imaginaryNumberUnsupported() {
error("imaginary number unsupported");
}
inline void Bigint::error(const string& __s) {
fprintf(stderr, "%s\n", __s.c_str());
cerr << __s << endl;
abort();
} //math
inline Bigint abs(const Bigint& __x) {
return Bigint(__x).abs();
}
inline Bigint pow(const Bigint& __x, const unsigned& __y) {
return Bigint(__x).pow(__y);
}
inline Bigint root(const Bigint& __x, const unsigned& __y = 2) {
return Bigint(__x).root(__y);
}
inline Bigint sqrt(const Bigint& __x) {
return Bigint(__x).sqrt();
} //io
inline istream& operator>>(istream& __s, Bigint& __t) {
string __r;
__s >> __r;
__t = Bigint(__r);
return __s;
}
inline ostream& operator<<(ostream& __s, const Bigint& __t) {
if (__t.neg()) __s << '-';
vicrit i = __t.num().rbegin();
__s << *i;
while (++i != __t.num().rend()) {
__s.width(length);
__s.fill('0');
__s << *i;
}
return __s;
} //optimization
inline void enoughMemory() {
__enoughMemory = true;
} #endif

  

05-11 13:16