(from zyf)
#ifndef MY_BIGN_H
#define MY_BIGN_H 1
#pragma GCC system_header
#include<cstring>
#include<algorithm>
#include<iostream>
using std::max;
using std::istream;
using std::ostream;
using std::string;
namespace zyf {
struct bign {
static const int maxlen=5000,limit=10000,width=4;
int len,bit[maxlen];
int& operator[](int p) {
return bit[p];
}
void ClearBit() {
memset(bit,0,sizeof(bit));
}
void Delete0() {
for(; !bit[len-1] && len>1; --len);
}
bign(int p=0) {
*this=p;
}
bign& operator=(int p) {
ClearBit();
len=p?0:1;
for(; p; p/=limit) bit[len++]=p%limit;
return *this;
}
bign(const char *p) {
*this=p;
}
bign& operator=(const char *p) {
ClearBit();
len=0;
for(int i=strlen(p)-1; i>=0; i-=4) {
int now=0;
for(int j=max(0,i-width+1); j<=i; ++j) now=now*10+(p[j]-'0');
bit[len++]=now;
}
return *this;
}
bign& operator+=(bign b) {
len=max(len,b.len)+1;
for(int i=0; i<len; ++i) bit[i]+=b[i],bit[i+1]+=bit[i]/limit,bit[i]%=limit;
Delete0();
return *this;
}
bign& operator-=(bign b) {
for(int i=0; i<len; ++i) {
bit[i]-=b[i];
if(bit[i]<0) bit[i]+=limit,--bit[i+1];
}
Delete0();
return *this;
}
bign& operator*=(bign b) {
bign a=*this;
ClearBit();
len=a.len+b.len;
for(int i=0; i<a.len; ++i)
for(int j=0; j<b.len; ++j)
bit[i+j]+=a[i]*b[j],bit[i+j+1]+=bit[i+j]/limit,bit[i+j]%=limit;
Delete0();
return *this;
}
bign& operator/=(int b) {
for(int i=len-1; i>0; --i) bit[i-1]+=limit*(bit[i]%b),bit[i]/=b;
bit[0]/=b;
Delete0();
return *this;
}
bool operator<(bign b) const {
if(len>b.len) return false;
if(len<b.len) return true;
for(int i=len-1; i>=0; --i)
if(bit[i]!=b[i]) return bit[i]<b[i];
return bit[0]<b[0];
}
bool operator==(bign b) const {
return !(*this<b) && !(b<*this);
}
bool operator!=(bign b) const {
return !(*this==b);
}
bool operator>(bign b) const {
return !(*this<b) && !(*this==b);
}
bool operator<=(bign b) const {
return *this<b || *this==b;
}
bool operator>=(bign b) const {
return *this>b || *this==b;
}
bool odd() {
return bit[0]%2==1;
}
bool even() {
return bit[0]%2==0;
}
};
bign operator+(bign a,bign b) {
return a+=b;
}
bign operator-(bign a,bign b) {
return a-=b;
}
bign operator*(bign a,bign b) {
return a*=b;
}
bign operator/(bign a,int b) {
return a/=b;
}
istream& operator>>(istream &is,bign &p) {
string s;
is>>s;
p=s.c_str();
return is;
}
ostream& operator<<(ostream &os,bign p) {
os.fill('0');
os<<p.bit[p.len-1];
for(int i=p.len-2; i>=0; --i) {
os.width(bign::width);
os<<p.bit[i];
}
return os;
}
bign sqrt(bign x) {
bign head=1,tail=x;
while(head<=tail) {
bign mid=(head+tail)/2;
if(x<mid*mid) tail=mid-1;
else head=mid+1;
}
return tail;
}
}
using zyf::bign;
#endif