#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX_LEN = 1001, CARRY = 4, BASE = 10000;
struct BigInt
{
private:
int A[MAX_LEN];
int Len;
public:
void Clear()
{
memset(A, 0, sizeof(A));
Len = 0;
}
void Set(int x)
{
Clear();
while (x)
{
A[Len++] = x%BASE;
x /= BASE;
}
while (Len > 0 && !A[Len])
Len--;//规定动作不要改
}
BigInt() { Clear(); }
BigInt(int x) { Set(x); }
void Read(char *s)
{
Clear();
int cur = 0, pos = 0, pow = 1;
for (int i = strlen(s) - 1; i >= 0; i--)//易忘点:倒序循环。因为位数小的数字在右边。//易忘点:-1
{
cur += (s[i] - '0')*pow;
pow *= 10;//易忘点
if (++pos == CARRY)
{
A[Len++] = cur;
cur = pos = 0;
pow = 1;
}
}
if (!pos)//最好按照pos来判断。
Len--;
else
A[Len] = cur;
}
void Read()
{
char s[MAX_LEN*CARRY];
scanf("%s", s);
Read(s);
}
void Print()
{
printf("%d", A[Len]);//易忘点。否则输出的数字前面多了几个0.
for (int i = Len - 1; i >= 0; i--)
printf("%0*d", CARRY, A[i]);//易忘点:%0*d。否则每一位前面的几个0没有输出。
printf("
");
}
BigInt operator = (const BigInt &a)
{
memcpy(A, a.A, sizeof(A));
Len = a.Len;
return *this;
}
bool operator < (const BigInt &a)
{
if (Len != a.Len)
return Len < a.Len;
for (int i = Len; i >= 0; i--)
if (A[i] != a.A[i])
return A[i] < a.A[i];
return false;
}
BigInt operator += (const BigInt &a)
{
Len = max(Len, a.Len);
for (int i = 0; i <= max(Len, a.Len); i++)
{
A[i] = (A[i] + a.A[i]);
A[i + 1] += A[i] / BASE;//易忘点:不是(A[i]+a.A[i])/BASE,因为A[i]是修改后的值
A[i] %= BASE;//易忘点:不要与第一句写在一起。//易忘点:此句和上一句/和%不要写反了
}
if (A[Len + 1])
Len++;
return *this;
}
BigInt operator + (const BigInt &a)
{
BigInt ans = *this;
return ans += a;
}
BigInt operator -= (const BigInt &a)
{
for (int i = 0; i <= Len; i++)
{
A[i] -= a.A[i];
if (A[i] < 0)
{
A[i] += BASE;
A[i + 1]--;//易忘点:借位是-,不是+
}
}
while (Len > 0 && !A[Len])//易忘点:Len>0
Len--;
return *this;
}
BigInt operator - (const BigInt &a)
{
BigInt ans = *this;
return ans -= a;
}
BigInt operator *= (const BigInt &a)
{
BigInt b = *this;
Clear();
Len = a.Len + b.Len;//以上3句 易忘点:乘法不是在原有乘数的基础上修改出来的,而是一个全新的数字
for (int i = 0; i <= a.Len; i++)
{
for (int j = 0; j <= b.Len; j++)
{
A[i + j] += a.A[i] * b.A[j];//易忘点:a. , b.//易忘点:+=,而不是=。相乘的结果最后是要累加的。
A[i + j + 1] += A[i + j] / BASE;//易忘点:A[i+j],而不是a.A[i]*b.A[j]
A[i + j] %= BASE;//易忘点:此句不可以与第一句结合在一起,因为第二句要用。
}
}
if (A[Len + 1])
Len++;
return *this;
}
BigInt operator * (const BigInt &a)
{
BigInt ans = *this;
return ans *= a;
}
BigInt operator /= (const int x)
{
for (int i = Len; i >= 0; i--)
{
if (i > 0)
A[i - 1] += A[i] % x * BASE;
A[i] /= x;//易忘点:此句并非在if的上面,否则if中的A[i]就是修改后的值了
}
while (Len > 0 && !A[Len])
//while(A[0]>0&&A[Len]<=0)
Len--;
return *this;
}
BigInt operator / (const int x)
{
BigInt ans = *this;
return ans /= x;
}
BigInt operator /= (const BigInt &a)
{
BigInt l, r = *this, one(1);//易忘点:r!=Len, l!=1(*this可能表示0)//易忘点:不能写one=1,因为声明时的=与重定义的=不是一个=
while (l < r)
{
BigInt mid = (l + r + one) / 2;
if (*this < (mid * a))//易忘点:<两边不要写反了,此判断说明当前的a选大了。
r = mid - one;
else
l = mid;
}
return *this = l;
}
BigInt operator / (const BigInt &a)
{
BigInt ans = *this;
return ans /= a;
}
bool IsZero()
{
return Len == 0 && A[0] == 0;
}
};