#include <algorithm>
using std::min;
using std::max;
typedef unsigned long long ull;
typedef long long ll;
constexpr ull BASE = 100000000;
constexpr unsigned LEN = 10000/8 +5;
struct Big{
ull num[LEN];
int dig=0;
void read(){
char ch[LEN*8];
int siz = 0;
char c = getchar();
while(c=='\n' || c=='\r') c=getchar();
while(!(c=='\n' || c=='\r' || c==EOF)){
ch[siz++] = c-'0';
c = getchar();
}
--siz;
int base = 1, now = 0;
for(int i=0; i<=siz; ++i){
now += ch[siz-i] * base;
base *= 10;
if(base == BASE){
base = 1;
num[dig++] = now;
now = 0;
}
}
num[dig++] = now;
}
void outp(){
if(!dig) return;
int i=dig-1;
printf("%llu", num[dig-1]);
if(i) do{
--i;
printf("%08llu", num[i]);
} while(i);
}
void cary(){
ull carry = 0;
for(int i=0; i<dig; ++i){
num[i] += carry;
carry = num[i] / BASE;
num[i] %= BASE;
}
while(carry){
num[dig++] = carry%BASE;
carry /= BASE;
}
}
Big& operator+=(Big b){
dig = max(dig, b.dig);
for(int i=0; i<dig; ++i){
num[i] += b.num[i];
}
this->cary();
return *this;
}
bool operator<(Big b){
if(dig == b.dig){
for(int i=dig; i>=0; --i)
if(num[i] != b.num[i]) return num[i] < b.num[i];
}
else return dig<b.dig;
return false;
}
bool operator==(Big b){
if(dig != b.dig) return false;
for(int i=0; i<dig; ++i){
if(num[i] != b.num[i]) return false;
}
return true;
}
Big& operator-=(Big b){
// ensure a > b
bool carry = 0;
int newdig = 0;
int maxlen = max(dig, b.dig);
for(int i=0; i<maxlen; ++i){
num[i] += (BASE - b.num[i] - carry);
if(num[i] >= BASE){
num[i] -= BASE;
carry = 0;
} else carry = 1;
if(num[i]) newdig = i;
}
dig = newdig+1;
return *this;
}
Big& half(){
if(!dig) return *this;
num[0] >>= 1;
for(int i=1; i<dig; ++i){
num[i-1] += ((num[i]&1)*BASE)>>1;
num[i] >>= 1;
}
if(!num[dig-1]) dig--;
return *this;
}
Big& operator<<=(unsigned times){
// << 37 : inside ull
constexpr int MOST = 37;
while(times>MOST){
*this <<= MOST;
times -= MOST;
}
for(int i=0; i<dig; ++i){
num[i] <<= times;
}
this->cary();
return *this;
}
bool iseven(){
return !(num[0]&1);
}
};
Big gcd(Big a, Big b){
int at=0, bt=0;
while(a.iseven()) a.half(), ++at;
while(b.iseven()) b.half(), ++bt;
for(;;){
while(a.iseven()) a.half();
while(b.iseven()) b.half();
if(a==b) break;
if(a<b) std::swap(a, b);
a-=b;
}
return a <<= min(at, bt);
}
标签:return,int,Big,dig,while,num,高精,模板
From: https://www.cnblogs.com/x383494/p/17062676.html