高精度入土
既然是高精度入土,分享一个姬昌无比的恶臭高精,可以处理负数。
\(M\) 用来调节字符串的长度,重载了 \(+\) \(-\) \(\times\) \(\div\) \(\%\) 五则运算。甚至还有快速幂。
重载了 \(\leq\) 等等二元关系
一些函数
GJ tmp;
turnGJ(1); //将整型的 1 转换成 GJ 类型的
tmp.clean(); //将这个东西的每一位变成零(初始化)
tmp.Read(); //快读它
tmp.Write(0 or 1) // 1 表示带换行的输出,而 0 表示不换行
tmp.itoBig(1) //将 tmp 初值赋为 1
tmp.qpow(tmp,1000) //求 tmp^1000
struct GJ{
static const int M=20087;
int num[M+10],len;
bool __fu;
GJ(){clean();}
void clean(){
memset(num,0,sizeof(num));
len=1;
__fu=0;
}
void Read(){
char str[M+10];
scanf("%s",str);
len=strlen(str);
if(str[0]=='-'){
__fu=1;
for(register int i=1;i<len;++i)
num[i]=str[len-i]-'0';
len--;
}else{
for(register int i=1;i<=len;++i)
num[i]=str[len-i]-'0';
}
}
void Write(bool IakIOI){
if(__fu) putchar('-');
for(register int i=len;i>=1;--i)
putchar(num[i]+'0');
if(IakIOI) puts("");
else /*您输出了空气。*/;
}
template <typename T>inline void itoBig(T x){
clean();
while(x!=0){
num[len++]=x%10;
x/=10;
}
if(len!=1)len--;
}
template <typename T>inline GJ turnGJ(T x){
GJ ___gj;
if(x<0){
x=abs(x);
___gj.__fu=1;
}
while(x!=0){
___gj.num[___gj.len++]=x%10;
x/=10;
}
if(___gj.len!=1)___gj.len--;
return ___gj;
}
bool operator < (const GJ &cmp)const{
if(len!=cmp.len) return len<cmp.len;
for(int i=len;i>=1;--i)
if(num[i]!=cmp.num[i]) return num[i]<cmp.num[i];
return false;
}
bool operator > (const GJ &cmp)const{return cmp<*this;}
bool operator <= (const GJ &cmp)const{return !(cmp<*this);}
bool operator != (const GJ &cmp)const{return cmp<*this||*this<cmp;}
bool operator == (const GJ &cmp)const{return !(cmp<*this||*this<cmp);}
GJ operator + (const GJ &A)const{
if(A.__fu&&__fu){
auto _____tmp=*this,____tmp=A;
_____tmp.__fu=0;____tmp.__fu=0;
auto ___S=_____tmp+____tmp;
___S.__fu=1;
return ___S;
}
if(A.__fu){
auto ____tmp=A;
____tmp.__fu=0;
auto ___S=*this-____tmp;
return ___S;
}
if(__fu){
auto ___tmp=*this;
___tmp.__fu=0;
auto ___S=A-___tmp;
return ___S;
}
GJ S;
S.len=max(len, A.len);
for(int i=1;i<=S.len;++i){
S.num[i]+=num[i]+A.num[i];
if(S.num[i]>=10){
S.num[i]-=10;
S.num[i+1]++;
}
}
while(S.num[S.len+1])S.len++;
return S;
}
GJ operator - (const GJ &A)const{
if(A.__fu&&__fu){
auto _S=A;
_S.__fu=0;
auto __S=*this+_S;
return __S;
}
if(A.__fu){
auto _S=A;
_S.__fu=0;
auto __S=*this+_S;
return __S;
}
if(__fu){
GJ _tmpp,_tmppp;
_tmpp=*this;
_tmpp.__fu=0;
_tmppp=A;
_tmppp.__fu=0;
auto SSS=_tmpp+_tmppp;
SSS.__fu=1;
return SSS;
}
if(*this<A){
putchar('-');
auto S=A-*this;
return S;
}
GJ S;
S.len=max(len,A.len);
for(int i=1;i<=S.len;++i){
S.num[i]+=num[i]-A.num[i];
if(S.num[i]<0){
S.num[i]+=10;
S.num[i+1]--;
}
}
while(!S.num[S.len]&&S.len>1)S.len--;
return S;
}
GJ operator * (const GJ &A)const{
GJ S;
if((A.__fu xor __fu)) S.__fu=1;
if((A.len==1&&A.num[1]==0)||(len==1&&num[1]==0)) return S;
S.len=A.len+len-1;
for(int i=1;i<=len;++i)
for(int j=1;j<=A.len;++j){
S.num[i+j-1]+=num[i]*A.num[j];
S.num[i+j]+=S.num[i+j-1]/10;
S.num[i+j-1]%=10;
}
while(S.num[S.len+1])S.len++;
return S;
}
GJ operator / (const GJ &A)const{
GJ S;
if((A.__fu xor __fu)) S.__fu=1;
if((A.len==1&&A.num[1]==0)||(len==1&&num[1]==0))return S;
GJ R,N;
S.len=0;
for(int i=len;i>=1;--i){
N.itoBig(10);
R=R*N;
N.itoBig(num[i]);
R=R+N;
int flag=-1;
for(register int j=1;j<=10;++j){
N.itoBig(j);
if(N*A>R){
flag=j-1;
break;
}
}
S.num[++S.len]=flag;
N.itoBig(flag);
R=R-N*A;
}
for(register int i=1;i<=len/2;++i)swap(S.num[i],S.num[len-i+1]);
while(!S.num[S.len]&&S.len>1)S.len--;
return S;
}
GJ operator % (const GJ &A)const{
GJ S;
GJ P=*this/A;
S=*this-P*A;
return S;
}
GJ qpow (const GJ &A,int buff) const{
if(buff==1) return A;
GJ f=qpow(A,buff/2);
if(buff&1) return f*f*A;
else return f*f;
}
void operator = (const GJ &A){
for(register int i=1;i<=A.len;++i)
num[i]=A.num[i];
len=A.len;
__fu=A.__fu;
}
};