有时候需要用到大整数,这里放一个自己写的大整数结构体(BigInteger),实现的功能如下:
- 输入输出;
- 四则运算;
- 比较运算;
- 幂运算;
其中乘法运算和除法运算都是 O ( n 2 ) O(n^2) O(n2) 的复杂度。
struct BigInteger
{
#define SIZE(x) ((int)x.size())
std::vector<int> x; // 从低位往高位存储
bool sign; // 0:+ 1:-
// 构造
BigInteger(std::vector<int> y) {this->x=y;}
BigInteger(const BigInteger &y) {*this=y;}
BigInteger(const BigInteger *y) {*this=*y;}
BigInteger(const std::string &y) {*this=y;}
BigInteger(long long y=0) {*this=y;}
void squeeze()
{
while(SIZE(x) && x[SIZE(x)-1]==0) x.pop_back();
if(SIZE(x)==0) sign=0;
}
BigInteger abs() const
{
BigInteger ret(this);
ret.sign=0;
return ret;
}
// 赋值
BigInteger &operator = (const BigInteger &y)
{
this->x=y.x;
this->sign=y.sign;
squeeze();
return *this;
}
BigInteger &operator = (const std::string &y)
{
x.clear();
sign=(y[0]=='-');
for(int i=SIZE(y)-1;i>=sign;i--)
x.push_back(y[i]-'0');
squeeze();
return *this;
}
BigInteger &operator = (long long y)
{
x.clear();
sign=y<0;
y=std::abs(y);
while(y)
{
x.push_back(y%10);
y/=10;
}
squeeze();
return *this;
}
// 取负号
BigInteger operator - () const
{
BigInteger ret(this);
ret.sign=sign^1;
return ret;
}
// 四则运算
BigInteger operator + (const BigInteger &y) const
{
if(y.sign==1) {return *this-(-y);}
if(sign==1) {return y-(-*this);}
BigInteger ret;
int i=0,j=0;
while(i<SIZE(x) && j<SIZE(y.x)) ret.x.push_back(x[i++]+y.x[j++]);
while(i<SIZE(x)) ret.x.push_back(x[i++]);
while(j<SIZE(y.x)) ret.x.push_back(y.x[j++]);
ret.x.push_back(0);
for(i=0;i+1<SIZE(ret.x);i++) ret.x[i+1]+=ret.x[i]/10,ret.x[i]%=10;
ret.squeeze();
return ret;
}
BigInteger operator - (const BigInteger &y) const
{
if(y.sign==1) {return *this+(-y);}
if(sign==1) {return -((-*this)+y);}
if(*this<y) {return -(y-*this);}
BigInteger ret;
int i=0,j=0;
while(j<SIZE(y.x)) ret.x.push_back(x[i++]-y.x[j++]);
while(i<SIZE(x)) ret.x.push_back(x[i++]);
for(int i=0;i+1<SIZE(ret.x);i++) if(ret.x[i]<0) ret.x[i]+=10,ret.x[i+1]--;
ret.squeeze();
return ret;
}
BigInteger operator * (const BigInteger &y) const
{
BigInteger ret;
ret.sign=sign^y.sign;
for(int i=0;i<(SIZE(x)+SIZE(y.x))*2;i++) ret.x.push_back(0);
for(int i=0;i<SIZE(x);i++)
for(int j=0;j<SIZE(y.x);j++)
ret.x[i+j]+=x[i]*y.x[j];
for(int i=0;i<SIZE(ret.x) && (ret.x[i]>9 || ret.x[i+1]>0);i++)
ret.x[i+1]+=ret.x[i]/10, ret.x[i]%=10;
ret.squeeze();
return ret;
}
BigInteger operator / (const BigInteger &y) const
{
std::stack<int> st;
BigInteger tmp(0ll),ten(10ll);
assert(y!=tmp);
BigInteger t1=this->abs(),t2=y.abs();
for(int i=SIZE(t1.x)-1;i>=0;i--)
{
tmp=tmp*ten+t1.x[i];
int s=0;
while(tmp>=t2)
{
tmp=tmp-t2;
s++;
}
st.push(s);
}
tmp.x.clear();
while(!st.empty()) tmp.x.push_back(st.top()),st.pop();
delete &st; delete &t1; delete &t2;
tmp.sign=sign^y.sign;
tmp.squeeze();
return tmp;
}
BigInteger operator % (const BigInteger &y) const
{
return *this-*this/y*y;
}
BigInteger operator += (const BigInteger &y) {*this=*this+y; return *this;}
BigInteger operator -= (const BigInteger &y) {*this=*this-y; return *this;}
BigInteger operator *= (const BigInteger &y) {*this=*this*y; return *this;}
BigInteger operator /= (const BigInteger &y) {*this=*this/y; return *this;}
BigInteger operator %= (const BigInteger &y) {*this=*this%y; return *this;}
BigInteger operator ++ () {*this=*this+1; return *this;}
BigInteger operator -- () {*this=*this-1; return *this;}
BigInteger operator ^ (const BigInteger &y) const
{
BigInteger ret(1ll),k(y),a(this),zero(0ll);
while(k>zero)
{
if(k%2==1) ret*=a;
a*=a;
k/=2;
}
return ret;
}
// 比较
bool operator < (const BigInteger &y) const
{
if(sign==0 && y.sign==1) return 0;
if(sign==1 && y.sign==0) return 1;
if(sign==1 && y.sign==1) {return (-y)<(-*this);}
if(SIZE(x)<SIZE(y.x)) return 1;
else if(SIZE(x)>SIZE(y.x)) return 0;
for(int i=SIZE(x)-1;i>=0;i--)
{
if(x[i]<y.x[i]) return 1;
else if(x[i]>y.x[i]) return 0;
}
return 0;
}
bool operator > (const BigInteger &y) const {return y<*this;}
bool operator <= (const BigInteger &y) const {return !(y<*this);}
bool operator >= (const BigInteger &y) const {return !(*this<y);}
bool operator == (const BigInteger &y) const {return *this<=y && *this>=y;}
bool operator != (const BigInteger &y) const {return !(*this==y);}
// 输入输出
friend std::ostream &operator << (std::ostream &out,const BigInteger &y)
{
if(y.sign) out<<'-';
for(int i=SIZE(y.x)-1;i>=0;i--) out<<y.x[i];
if(SIZE(y.x)==0) out<<'0';
return out;
}
friend std::istream &operator >> (std::istream &in,BigInteger &y)
{
std::string s;
in>>s;
y=s;
return in;
}
};