高精度整合
函数整合
#include<cstdio>
#include<iostream>
#include<cstring>
#define ll long long
#define MAXN 400000
using namespace std;
char sa[MAXN],sb[MAXN];
int a[MAXN],b[MAXN],c[MAXN],d;
template<typename type>
inline void get(char sa[],type a[],bool mode)//读入一个数,按位存到a数组中,mode为0正序存,为1倒序存
{
memset(a,0,sizeof(a));
cin>>sa;
int len=strlen(sa);
if(mode) for(int i(1);i<=len;i++) a[i]=sa[len-i]^48;
else for(int i(1);i<=len;i++) a[i]=sa[i-1]^48;
}
template<typename type>
inline void put(int len,type c[],bool mode)//按位输出一个长度为len的数组,mode为0正序输出,为1倒序输出
{
if(mode) for(int i(len);i>0;i--) cout<<c[i];
else for(int i(1);i<=len;i++) cout<<c[i];
puts("");
}
//高精度加法
template<typename type>
inline void add(char sa[],char sb[],type a[],type b[],type c[])
{
memset(c,0,sizeof(c));
get(sa,a,1);
get(sb,b,1);
int lena=strlen(sa),lenb=strlen(sb),lenc(0),carry(0);//carry存进位
while(lenc<=lena||lenc<=lenb)
{
c[lenc]=a[lenc]+b[lenc]+carry;
carry=c[lenc]/10;
c[lenc]%=10;
lenc++;
}
c[lenc]=carry;
while((!c[lenc])&&lenc>1) lenc--;
put(lenc,c,1);
return;
}
//高精度减法
template<typename type>
inline void sub(char sa[],char sb[],type a[],type b[],type c[])
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
cin>>sa>>sb;
int lena=strlen(sa),lenb=strlen(sb),lenc(0);
char temp[MAXN];
//"||"的优先级低于"&&" //strcmp()为字符串比较函数,sa==sb返回0,s1>s2返回一个正整数,s1<s2返回一个负整数
if(lena<lenb || (lena==lenb)&&strcmp(sa,sb)<0)//处理被减数小于减数的情况
{
strcpy(temp,sa);//将字符串sa复制到temp
strcpy(sa,sb);
strcpy(sb,temp);
putchar('-');
lena=strlen(sa),lenb=strlen(sb);
}
for(int i(1);i<=lena;i++) a[i]=sa[lena-i]^48;
for(int i(1);i<=lenb;i++) b[i]=sb[lenb-i]^48;
while(lenc<=lena||lenc<=lenb)
{
if(a[lenc]<b[lenc])
{
a[lenc]+=10;
a[lenc+1]--;
}
c[lenc]=a[lenc]-b[lenc];
lenc++;
}
while((!c[lenc])&&lenc>1) lenc--;
put(lenc,c,1);
return;
}
//高精度乘法
template<typename type>
inline void mul(char sa[],char sb[],type a[],type b[],type c[])
{
memset(c,0,sizeof(c));
get(sa,a,1);
get(sb,b,1);
int lena=strlen(sa),lenb=strlen(sb),lenc(0),carry(0);
for(int i(1);i<=lena;i++)
{
carry=0;
for(int j(1);j<=lenb;j++)
{
c[i+j-1]=c[i+j-1]+a[i]*b[j]+carry;
carry=c[i+j-1]/10;
c[i+j-1]%=10;
}
c[i+lenb]=carry;
}
lenc=lena+lenb;
while((!c[lenc])&&lenc>1) lenc--;
put(lenc,c,1);
return;
}
//高精度除法-高精除以低精(整除)
template<typename type>
inline void div1(char sa[],type a[],type b,type c[])
{
memset(a,0,sizeof(a));
memset(c,0,sizeof(c));
cin>>sa>>b;
if(!b)
{
puts("0");
return;
}
int lena=strlen(sa),lenc(0);
ll carry(0);
for(int i(1);i<=lena;i++) a[i]=sa[i-1]^48;
for(int i(1);i<=lena;i++)//对被除数的每一位(包括余数)都除以除数
{
c[i]=(carry*10+a[i])/b;
carry=(carry*10+a[i])%b;
}
lenc=1;
while((!c[lenc])&&lenc<lena) lenc++;
for(int i=lenc;i<=lena;i++) cout<<c[i];
}
//高精度除法-高精除以高精(整除)
//用减法模拟除法,对被除数的每一位(包括余数)都减去除数,直到当前位置的数字(包括余数)小于除数
template<typename type>
inline int comp(type a[],type b[])//比较a和b的大小关系,若a>b则为1,若a<b则为-1,若a=b则为0(类似于strcmp)
{
if(a[0]>b[0]) return 1;
if(a[0]<b[0]) return -1;
for(int i=a[0];i>0;i--) //从最高位开始比较
{
if(a[i]>b[i]) return 1;
if(a[i]<b[i]) return -1;
}
return 0;
}
template<typename type>
inline void sub2(type a[],type b[])//计算a=a-b
{
int flag=comp(a,b);
if(!flag)
{
a[0]=0;
return;
}
if(flag=1)
{
for(int i=1;i<=a[0];i++)
{
if(a[i]<b[i])
{
a[i]+=10;
a[i+1]--;
}
a[i]-=b[i];
}
while((!a[a[0]])&&a[0]>0) a[0]--;
return;
}
}
template<typename type>
inline void div2(char sa[],char sb[],type a[],type b[],type c[])//在这里,x[0]存储的是x的位数
{
memset(c,0,sizeof(c));
get(sa,a,1);//因为是逆序存,a[1]就是个位,a[lena]就是最高位
get(sb,b,1);
int lena=strlen(sa),lenb=strlen(sb),lenc(0),carry(0),temp[MAXN];
if(lenb==1&&(!b))
{
puts("0");
return;
}
a[0]=lena,b[0]=lenb,c[0]=a[0]-b[0]+1;//商的位数不超过被除数的位数-除数的位数+1
for(int i=c[0];i>0;i--)
{
memset(temp,0,sizeof(temp));
for(int j=1;j<=b[0];j++) temp[j+i-1]=b[j];//复制b数组到temp数组从i开始的地方
temp[0]=b[0]+i-1;
while(comp(a,temp)>=0)
{
c[i]++;
sub2(a,temp);
}
}
while((!c[c[0]])&&c[0]>0) c[0]--;//处理前导0
if(!c[0]) puts("0");//输出商
else
{
for(int i=c[0];i>0;i--) cout<<c[i];
puts("");
}
if(!a[0]) puts("0");//输出余数
else
{
for(int i=a[0];i>0;i--) cout<<a[i];
puts("");
}
return;
}
signed main()
{
add(sa,sb,a,b,c);
sub(sa,sb,a,b,c);
mul(sa,sb,a,b,c);
div1(sa,a,d,c);
div2(sa,sb,a,b,c);
return 0;
}
结构体封装
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=500;
struct HA_int
{
int len,s[MAXN];
HA_int()
{
memset(s,0,sizeof(s));
len=1;
}
HA_int(int num){*this=num;}
HA_int(const char *num){*this=num;}
HA_int operator =(const int num)
{
char s[MAXN];
sprintf(s,"%d",num);
*this=s;
return *this;
}
HA_int operator =(const char *num)
{
for(int i=0;num[i]=='0';num++);
len=strlen(num);
for(int i=0;i<len;i++) s[i]=num[len-i-1]^48;
return *this;
}
HA_int operator +(const HA_int &b)const
{
HA_int c;
c.len=0;
for(int i=0,g=0;g||i<max(len,b.len);i++)
{
int x=g;
if(i<len)x+=s[i];
if(i<b.len)x+=b.s[i];
c.s[c.len++]=x%10;
g=x/10;
}
return c;
}
HA_int operator +=(const HA_int &b)
{
*this=*this+b;
return *this;
}
void clear()
{
while(len>1 && !s[len-1]) len--;
}
HA_int operator *(const HA_int &b)
{
HA_int c;
c.len=len+b.len;
for(int i=0;i<len;i++)
for(int j=0;j<b.len;j++)
c.s[i+j]+=s[i]*b.s[j];
for(int i=0;i<c.len;i++)
{
c.s[i+1]+=c.s[i]/10;
c.s[i]%=10;
}
c.clear();
return c;
}
HA_int operator *=(const HA_int &b)
{
*this=*this*b;
return *this;
}
HA_int operator -(const HA_int &b)
{
HA_int c;
c.len=0;
for(int i=0,g=0;i<len;i++)
{
int x=s[i]-g;
if(i<b.len)x-=b.s[i];
if(x>=0) g=0;
else
{
g=1;
x+=10;
}
c.s[c.len++]=x;
}
c.clear();
return c;
}
HA_int operator -=(const HA_int &b)
{
*this=*this-b;
return *this;
}
HA_int operator /(const HA_int &b)
{
HA_int c,f=0;
for(int i=len-1;i>=0;i--)
{
f*=10;
f.s[0]=s[i];
while(f>=b)
{
f-=b;
c.s[i]++;
}
}
c.len=len;
c.clear();
return c;
}
HA_int operator /=(const HA_int &b)
{
*this=*this/b;
return *this;
}
HA_int operator %(const HA_int &b)
{
HA_int r=*this/b;
r=*this-r*b;
return r;
}
HA_int operator %=(const HA_int &b)
{
*this=*this%b;
return *this;
}
bool operator <(const HA_int &b)
{
if(len!=b.len) return len<b.len;
for(int i=len-1;i>=0;i--)
{
if(s[i]!=b.s[i]) return s[i]<b.s[i];
}
return false;
}
bool operator >(const HA_int &b)
{
if(len!=b.len) return len>b.len;
for(int i=len-1;i>=0;i--)
{
if(s[i]!=b.s[i]) return s[i]>b.s[i];
}
return false;
}
bool operator ==(const HA_int &b)
{
return !(*this>b) && !(*this<b);
}
bool operator !=(const HA_int &b)
{
return !(*this==b);
}
bool operator <=(const HA_int &b)
{
return *this<b || *this==b;
}
bool operator >=(const HA_int &b)
{
return *this>b || *this==b;
}
string str()const
{
string res="";
for(int i=0;i<len;i++) res=char(s[i]+'0')+res;
return res;
}
};
istream& operator >>(istream &in,HA_int &x)
{
string s;
in>>s;
x=s.c_str();
return in;
}
ostream& operator <<(ostream &out,const HA_int &x)
{
out<<x.str();
return out;
}
signed main()
{
HA_int a,b;
cin>>a>>b;
cout<<a+b<<endl<<a-b<<endl<<a*b<<endl<<a/b<<endl;
return 0;
}
类封装「普通版」
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1010
using namespace std;
namespace ly
{
auto max=[](const auto &x,const auto &y)->auto{return x>y?x:y;};
}
template<typename type>
inline void read(type &x)
{
x=0;bool flag(0);char ch=getchar();
while(!isdigit(ch)) flag^=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
flag?x=-x:0;
}
template<typename type>
inline void write(type x,bool flag=1)
{
x<0?x=-x,putchar('-'):0;static short Stack[50],top(0);
do Stack[++top]=x%10,x/=10;while(x);
while(top) putchar(Stack[top--]|48);
flag?putchar('\n'):putchar(' ');
}
class _int
{
public:
int n,a[maxn];
void init(int x=1){n=x,memset(a,0,sizeof(a));}
_int(){init();}
template<typename type>
_int(type x){init(!x);while(x)a[++n]=x%10,x/=10;}
template<typename type>
type operator =(type x){init(!x);while(x)a[++n]=x%10,x/=10;return x;}
void clear(){while(n>1&&!a[n])n--;}
friend void read(_int &x)
{
x.init(0);char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) x.a[++x.n]=ch^48,ch=getchar();
reverse(x.a+1,x.a+x.n+1),x.clear();
}
friend void write(_int x,bool flag=1)
{
for(int i=x.n;i>=1;--i) putchar(x.a[i]|48);
flag?putchar('\n'):putchar(' ');
}
friend _int operator +(const _int &a,const _int &b)
{
_int c;c.n=ly::max(a.n,b.n);
for(int i=1;i<=c.n;++i)
{
c.a[i]+=a.a[i]+b.a[i];
if(c.a[i]>=10) c.a[i+1]++,c.a[i]-=10;
}
if(c.a[c.n+1]) c.n++;
return c;
}
friend _int operator -(const _int &a,const _int &b)
{
_int c;c.n=a.n;
for(int i=1;i<=c.n;++i)
{
c.a[i]+=a.a[i]-b.a[i];
if(c.a[i]<0) c.a[i+1]--,c.a[i]+=10;
}
c.clear();
return c;
}
friend _int operator *(const _int &a,int b)
{
_int c;c.n=a.n;
for(int i=1;i<=c.n;++i)
{
c.a[i]+=a.a[i]*b;
if(c.a[i]>=10) c.a[i+1]+=c.a[i]/10,c.a[i]%=10;
}
while(c.a[c.n+1]) c.a[c.n+2]+=c.a[c.n+1]/10,c.a[c.n+1]%=10,c.n++;
c.clear();
return c;
}
friend _int operator /(const _int &a,int b)
{
_int c;c.n=a.n;int r=0;
for(int i=c.n;i>=1;--i) r=(r<<1)+(r<<3)+a.a[i],c.a[i]=r/b,r%=b;
c.clear();
return c;
}
friend _int operator %(const _int &a,int b){return a-a/b*b;}
_int operator +=(const _int &a){*this=*this+a;return *this;}
_int operator -=(const _int &a){*this=*this-a;return *this;}
_int operator *=(int a){*this=*this*a;return *this;}
_int operator /=(int a){*this=*this/a;return *this;}
_int operator %=(int a){*this=*this%a;return *this;}
_int operator ++(){*this=*this+1;return *this;}
_int operator --(){*this=*this-1;return *this;}
template<typename type>
_int operator ++(type){++*this;return *this-1;}
template<typename type>
_int operator --(type){--*this;return *this+1;}
friend bool operator <(const _int &a,const _int &b)
{
if(a.n^b.n) return a.n<b.n;
for(int i=a.n;i>=1;--i) if(a.a[i]^b.a[i]) return a.a[i]<b.a[i];
return false;
}
friend bool operator >(const _int &a,const _int &b)
{
if(a.n^b.n) return a.n>b.n;
for(int i=a.n;i>=1;--i) if(a.a[i]^b.a[i]) return a.a[i]>b.a[i];
return false;
}
friend bool operator ==(const _int &a,const _int &b)
{
if(a.n^b.n) return false;
for(int i=a.n;i>=1;--i) if(a.a[i]^b.a[i]) return false;
return true;
}
friend bool operator <=(const _int &a,const _int &b){return !(a>b);}
friend bool operator >=(const _int &a,const _int &b){return !(a<b);}
friend _int operator *(const _int &a,const _int &b)
{
_int c;c.n=a.n+b.n;
for(int i=1;i<=a.n;++i)
for(int j=1;j<=b.n;++j)
c.a[i+j-1]+=a.a[i]*b.a[j];
for(int i=1;i<=c.n;++i) if(c.a[i]>=10) c.a[i+1]+=c.a[i]/10,c.a[i]%=10;
c.clear();
return c;
}
friend _int operator /(const _int a,const _int b)
{
_int c,r=0;c.n=a.n;
for(int i=c.n;i>=1;--i)
{
r=r*10+a.a[i];
while(r>=b) r-=b,c.a[i]++;
}
c.clear();
return c;
}
friend _int operator %(const _int &a,const _int &b){return a-a/b*b;}
_int operator *=(const _int &a){*this=*this*a;return *this;}
_int operator /=(const _int &a){*this=*this/a;return *this;}
_int operator %=(const _int &a){*this=*this%a;return *this;}
};
signed main()
{
_int a,b,c;int d;
read(a),read(b);
write(a+b),write(a-b),write(a*b),write(a/b),write(a%b);
read(c),read(d);
write(c+d),write(c-d),write(c*d),write(c/d),write(c%d);
return 0;
}
注意:结构体、类封装的不能出现负数!「哪个题要用到负的高精只能说出题人没🐴」
类封装「内存池」
为了避免频繁申请、释放空间造成的效率降低,可以使用内存池进行优化。
具体的实现方法是:提前开辟好可能使用的最大空间,使用队列存储可使用的空间。申请空间时取出队头,释放空间时加入队列即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1010
#define ll long long
using namespace std;
namespace IO
{
template<typename type>
inline void read(type &x)
{
x=0;bool flag(0);char ch=getchar();
while(!isdigit(ch)) flag^=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
flag?x=-x:0;
}
template<typename type>
inline void write(type x,bool flag=1)
{
x<0?x=-x,putchar('-'):0;static short Stack[50],top(0);
do Stack[++top]=x%10,x/=10;while(x);
while(top) putchar(Stack[top--]|48);
flag?putchar('\n'):putchar(' ');
}
}using namespace IO;
namespace ly
{
auto max=[](const auto &x,const auto &y)->auto{return x>y?x:y;};
class _int;
inline _int* _new();
inline _int _delete(_int *);
class _int
{
public:
int n,a[maxn];
void init(int x=1){n=x,memset(a,0,sizeof(a));}
void clear(){while(n>1&&!a[n])n--;}
_int(){init();}
template<typename type>
_int(type x){init(!x);while(x)a[++n]=x%10,x/=10;}
template<typename type>
_int operator =(type x){init(!x);while(x)a[++n]=x%10,x/=10;return *this;}
friend void read(_int &x)
{
x.init(0);char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) x.a[++x.n]=ch^48,ch=getchar();
reverse(x.a+1,x.a+x.n+1),x.clear();
}
friend void write(const _int &x,bool flag=1)
{
for(int i=x.n;i>=1;--i) putchar(x.a[i]|48);
flag?putchar('\n'):putchar(' ');
}
friend _int operator +(const _int &a,const _int &b)
{
_int *c=_new();c->n=ly::max(a.n,b.n);
for(int i=1;i<=c->n;++i)
{
c->a[i]+=a.a[i]+b.a[i];
if(c->a[i]>=10) c->a[i+1]++,c->a[i]-=10;
}
if(c->a[c->n+1]) c->n++;
return _delete(c);
}
friend _int operator -(const _int &a,const _int &b)
{
_int *c=_new();c->n=a.n;
for(int i=1;i<=c->n;++i)
{
c->a[i]+=a.a[i]-b.a[i];
if(c->a[i]<0) c->a[i+1]--,c->a[i]+=10;
}
c->clear();
return _delete(c);
}
template<typename type>
friend _int operator *(const _int &a,type b)
{
_int *c=_new();c->n=a.n;
for(int i=1;i<=c->n;++i)
{
c->a[i]+=a.a[i]*b;
if(c->a[i]>=10) c->a[i+1]+=c->a[i]/10,c->a[i]%=10;
}
while(c->a[c->n+1]) c->a[c->n+2]+=c->a[c->n+1]/10,c->a[c->n+1]%=10,c->n++;
c->clear();
return _delete(c);
}
template<typename type>
friend _int operator /(const _int &a,type b)
{
_int *c=_new();c->n=a.n;type r=0;
for(int i=c->n;i>=1;--i) r=(r<<1)+(r<<3)+a.a[i],c->a[i]=r/b,r%=b;
c->clear();
return _delete(c);
}
template<typename type>
friend _int operator %(const _int &a,type b)
{
_int *c=_new();c->n=a.n;type r=0;
for(int i=c->n;i>=1;--i) r=(r<<1)+(r<<3)+a.a[i],c->a[i]=r/b,r%=b;
*c=r;
return _delete(c);
}
_int operator +=(const _int &a){*this=*this+a;return *this;}
_int operator -=(const _int &a){*this=*this-a;return *this;}
template<typename type>
_int operator *=(const type &a){*this=*this*a;return *this;}
template<typename type>
_int operator /=(const type &a){*this=*this/a;return *this;}
template<typename type>
_int operator %=(const type &a){*this=*this%a;return *this;}
_int operator ++(){*this=*this+1;return *this;}
_int operator --(){*this=*this-1;return *this;}
template<typename type>
_int operator ++(type){*this=*this+1;return *this-1;}
template<typename type>
_int operator --(type){*this=*this-1;return *this+1;}
friend bool operator <(const _int &a,const _int &b)
{
if(a.n^b.n) return a.n<b.n;
for(int i=a.n;i>=1;--i) if(a.a[i]^b.a[i]) return a.a[i]<b.a[i];
return false;
}
friend bool operator >(const _int &a,const _int &b)
{
if(a.n^b.n) return a.n>b.n;
for(int i=a.n;i>=1;--i) if(a.a[i]^b.a[i]) return a.a[i]>b.a[i];
return false;
}
friend bool operator ==(const _int &a,const _int &b)
{
if(a.n^b.n) return false;
for(int i=a.n;i>=1;--i) if(a.a[i]^b.a[i]) return false;
return true;
}
friend bool operator !=(const _int &a,const _int &b){return !(a==b);}
friend bool operator <=(const _int &a,const _int &b){return !(a>b);}
friend bool operator >=(const _int &a,const _int &b){return !(a<b);}
bool operator !(){return this->n==1&&!(this->a[1]);}
friend _int operator *(const _int &a,const _int &b)
{
_int *c=_new();c->n=a.n+b.n;
for(int i=1;i<=a.n;++i)
for(int j=1;j<=b.n;++j)
c->a[i+j-1]+=a.a[i]*b.a[j];
for(int i=1;i<=c->n;++i) if(c->a[i]>=10) c->a[i+1]+=c->a[i]/10,c->a[i]%=10;
c->clear();
return _delete(c);
}
friend _int operator /(const _int &a,const _int &b)
{
_int *c=_new(),*r=_new();c->n=a.n,r->n=b.n;
for(int i=b.n;i>1;--i) r->a[i-1]=a.a[a.n-b.n+i];
for(int i=a.n-b.n+1;i>=1;--i)
{
*r=*r*10+a.a[i];
while(*r>=b) *r-=b,c->a[i]++;
}
c->clear(),_delete(r);
return _delete(c);
}
friend _int operator %(const _int &a,const _int &b)
{
_int *c=_new(),*r=_new();c->n=a.n,r->n=b.n;
for(int i=b.n;i>1;--i) r->a[i-1]=a.a[a.n-b.n+i];
for(int i=a.n-b.n+1;i>=1;--i)
{
*r=*r*10+a.a[i];
while(*r>=b) *r-=b,c->a[i]++;
}
r->clear(),_delete(c);
return _delete(r);
}
_int operator *=(const _int &a){*this=*this*a;return *this;}
_int operator /=(const _int &a){*this=*this/a;return *this;}
_int operator %=(const _int &a){*this=*this%a;return *this;}
}pool[maxn];
class queue
{
private:
int head,tail,n;
_int* a[maxn];
public:
void push(_int *x){a[tail]=x,tail=(++tail^maxn?tail:0),n++;}
void pop(){head=(++head^maxn?head:0),n--;}
_int* front(){return a[head];}
int size(){return n;}
bool empty(){return !n;}
queue(){head=tail=n=0;for(int i=0;i<maxn;++i)push(&pool[i]);}
}q;
inline _int* _new(){_int *t=q.front();t->init(),q.pop();return t;}
inline _int _delete(_int *p){q.push(p);return *p;}
}using ly::_int;
signed main()
{
_int a,b,c;int d;
read(a),read(b),read(c),read(d);
write(a+b),write(a-b),write(a*b),write(a/b),write(a%b);
write(c+d),write(c-d),write(c*d),write(c/d),write(c%d);
return 0;
}
类封装「更多操作」
#define LOCAL
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
namespace ly
{
namespace IO
{
#ifndef LOCAL
#define maxn (1<<20)
char _in[maxn],_out[maxn],*p1=_in,*p2=_in,*p3=_out;
#define getchar() (p1==p2&&(p2=(p1=_in)+fread(_in,1,maxn,stdin),p1==p2)?EOF:*p1++)
#define flush() (fwrite(_out,1,p3-_out,stdout))
#define putchar(ch) (p3==_out+maxn&&(flush(),p3=_out),*p3++=(ch))
class Flush{public:~Flush(){flush();}}_;
#endif
template<typename type>
inline type read(type &x)
{
x=0;bool flag(0);char ch=getchar();
while(!isdigit(ch)) flag^=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return flag?x=-x:x;
}
template<typename type>
inline void write(type x)
{
x<0?x=-x,putchar('-'):0;
static short Stack[50],top(0);
do Stack[++top]=x%10,x/=10;while(x);
while(top) putchar(Stack[top--]|48);
}
inline char read(char &x){return x=getchar();}
inline char write(const char &x){return putchar(x);}
template<typename type,typename...T>
inline void read(type &x,T&...y){read(x),read(y...);}
template<typename type,typename...T>
inline void write(const type &x,const T&...y){write(x),putchar(' '),write(y...),sizeof...(y)^1?0:putchar('\n');}
inline __int128 read(){__int128 x;return read(x);}
template<typename type>
inline type put(const type &x,bool flag=1){write(x),flag?putchar('\n'):putchar(' ');return x;}
#ifndef LOCAL
#undef maxn
#undef getchar
#undef flush
#undef putchar
#endif
}using namespace IO;
namespace algorithm
{
auto max=[](const auto &x,const auto &y)->auto{return x>y?x:y;};
}using namespace algorithm;
namespace INT
{
#define maxn 1000
class _int;
inline _int* _new();
inline _int _delete(_int *);
class _int
{
public:
int n;
int a[maxn];
void init(int x=1){n=x;for(int i=0;i<maxn;++i)if(a[i])a[i]=0;}
void clear(){while(n>1&&!a[n])n--;}
_int(){init();}
template<typename type>
_int operator =(type x){init(!x);while(x)a[++n]=x%10,x/=10;return *this;}
template<typename type>
_int(const type &x){*this=x;}
friend _int read(_int &x)
{
x.init(0);char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) x.a[++x.n]=ch^48,ch=getchar();
reverse(x.a+1,x.a+x.n+1),x.clear();return x;
}
friend _int write(const _int &x)
{
for(int i=x.n;i>=1;--i) putchar(x.a[i]|48);
return x;
}
inline int operator [](int i)const{return a[i];}
friend _int operator +(const _int &a,const _int &b)
{
_int *c=_new();c->n=ly::max(a.n,b.n);
for(int i=1;i<=c->n;++i)
{
c->a[i]+=a[i]+b[i];
if(c->a[i]>=10) c->a[i+1]++,c->a[i]-=10;
}
if(c->a[c->n+1]) c->n++;
return _delete(c);
}
friend _int operator -(const _int &a,const _int &b)
{
_int *c=_new();c->n=a.n;
for(int i=1;i<=c->n;++i)
{
c->a[i]+=a[i]-b[i];
if(c->a[i]<0) c->a[i+1]--,c->a[i]+=10;
}
c->clear();
return _delete(c);
}
template<typename type>
friend _int operator *(const _int &a,const type &b)
{
_int *c=_new();c->n=a.n;
for(int i=1;i<=c->n;++i)
{
c->a[i]+=a[i]*b;
if(c->a[i]>=10) c->a[i+1]+=c->a[i]/10,c->a[i]%=10;
}
while(c->a[c->n+1]) c->a[c->n+2]+=c->a[c->n+1]/10,c->a[c->n+1]%=10,c->n++;
c->clear();
return _delete(c);
}
template<typename type>
friend _int operator /(const _int &a,const type &b)
{
_int *c=_new();c->n=a.n;type r=0;
for(int i=c->n;i>=1;--i) r=(r<<1)+(r<<3)+a[i],c->a[i]=r/b,r%=b;
c->clear();
return _delete(c);
}
template<typename type>
friend _int operator %(const _int &a,const type &b)
{
_int *c=_new();c->n=a.n;type r=0;
for(int i=c->n;i>=1;--i) r=(r<<1)+(r<<3)+a[i],c->a[i]=r/b,r%=b;
*c=r;
return _delete(c);
}
inline _int operator +=(const _int &a){return *this=*this+a;}
inline _int operator -=(const _int &a){return *this=*this-a;}
template<typename type>
inline _int operator *=(const type &a){return *this=*this*a;}
template<typename type>
inline _int operator /=(const type &a){return *this=*this/a;}
template<typename type>
inline _int operator %=(const type &a){return *this=*this%a;}
inline _int operator ++(){return *this+=1;}
inline _int operator --(){return *this-=1;}
template<typename type>
inline _int operator ++(type){return ++*this-1;}
template<typename type>
inline _int operator --(type){return --*this+1;}
friend bool operator <(const _int &a,const _int &b)
{
if(a.n^b.n) return a.n<b.n;
for(int i=a.n;i>=1;--i) if(a[i]^b[i]) return a[i]<b[i];
return false;
}
friend bool operator >(const _int &a,const _int &b)
{
if(a.n^b.n) return a.n>b.n;
for(int i=a.n;i>=1;--i) if(a[i]^b[i]) return a[i]>b[i];
return false;
}
friend bool operator ==(const _int &a,const _int &b)
{
if(a.n^b.n) return false;
for(int i=a.n;i>=1;--i) if(a[i]^b[i]) return false;
return true;
}
friend bool operator !=(const _int &a,const _int &b){return !(a==b);}
friend bool operator <=(const _int &a,const _int &b){return !(a>b);}
friend bool operator >=(const _int &a,const _int &b){return !(a<b);}
inline bool operator !(){return n==1&&!a[1];}
friend bool operator &&(const _int &a,const _int &b){return a!=0&&b!=0;}
friend bool operator ||(const _int &a,const _int &b){return a!=0||b!=0;}
friend _int operator *(const _int &a,const _int &b)
{
_int *c=_new();c->n=a.n+b.n;
for(int i=1;i<=a.n;++i)
for(int j=1;j<=b.n;++j)
c->a[i+j-1]+=a[i]*b[j];
for(int i=1;i<=c->n;++i) if(c->a[i]>=10) c->a[i+1]+=c->a[i]/10,c->a[i]%=10;
c->clear();
return _delete(c);
}
friend _int operator /(const _int &a,const _int &b)
{
_int *c=_new(),*r=_new();c->n=a.n-b.n+1,r->n=b.n-1;
for(int i=b.n;i>1;--i) r->a[i-1]=a[a.n-b.n+i];
for(int i=a.n-b.n+1;i>=1;--i)
{
*r=*r*10+a[i];
while(*r>=b) c->a[i]++,*r-=b;
}
c->clear(),_delete(r);
return _delete(c);
}
friend _int operator %(const _int &a,const _int &b)
{
_int *c=_new(),*r=_new();c->n=a.n-b.n+1,r->n=b.n-1;
for(int i=b.n;i>1;--i) r->a[i-1]=a[a.n-b.n+i];
for(int i=a.n-b.n+1;i>=1;--i)
{
*r=*r*10+a[i];
while(*r>=b) c->a[i]++,*r-=b;
}
r->clear(),_delete(c);
return _delete(r);
}
inline _int operator *=(const _int &a){return *this=*this*a;}
inline _int operator /=(const _int &a){return *this=*this/a;}
inline _int operator %=(const _int &a){return *this=*this%a;}
}pool[maxn];
class queue
{
private:
int head,tail,n;
_int* a[maxn];
public:
void push(_int* x){a[tail]=x,tail=(++tail^maxn?tail:0),n++;}
void pop(){head=(++head^maxn?head:0),n--;}
_int* front(){return a[head];}
int size(){return n;}
bool empty(){return !n;}
queue(){head=tail=n=0;for(int i=0;i<maxn;++i)push(&pool[i]);}
}q;
inline _int* _new(){_int *t=q.front();q.pop(),t->clear();return t;}
inline _int _delete(_int *p){q.push(p);return *p;}
#undef maxn
}
}using namespace ly::IO;using namespace ly::INT;
_int a,b,c;int d;
signed main()
{
read(a,b,c,d);
put(a+b),put(a-b),put(a*b),put(a/b),put(a%b);
put(c+d),put(c-d),put(c*d),put(c/d),put(c%d);
return 0;
}
更快的高精度除法
参见:RSA系列——高精度除法
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#define maxn (1<<18)
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
const double pi=acos(-1);
struct cn{
double a,b;
cn(double a=0,double b=0):a(a),b(b){}
};
cn operator+(cn a,cn b){return cn(a.a+b.a,a.b+b.b);}
cn operator-(cn a,cn b){return cn(a.a-b.a,a.b-b.b);}
cn operator*(cn a,cn b){return cn(a.a*b.a-a.b*b.b,a.a*b.b+a.b*b.a);}
int rev[2*maxn+10];
void fft(cn *a,int t,int n,int f){
for(int i=1;i<n;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<t-1);
for(int i=0;i<n;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
for(int i=1;i<n;i<<=1){
cn wn(cos(pi/i),f*sin(pi/i));
for(int p=i<<1,j=0;j<n;j+=p){
cn w(1,0);
for(int k=j;k<j+i;k++){
cn x=a[k],y=w*a[k+i];
a[k]=x+y;
a[k+i]=x-y;
w=w*wn;
}
}
}
if(f==-1)for(int i=0;i<n;i++)a[i].a/=n,a[i].b/=n;
}
struct bint{
int a[10000],len;
void print(){
if(!len)puts("0");
else{
for(int i=len-1;i>=0;i--)printf("%d",a[i]);
putchar('\n');
}
}
bint(int x=0){
len=0;
clr(a,0);
while(x)a[len++]=x%10,x/=10;
}
void clear(int lim){
int m=len-lim;
for(int i=0;i<lim;i++)a[i]=a[i+m];
for(int i=lim;i<len;i++)a[i]=0;
len=lim;
}
};
bool operator==(const bint &a,const bint &b){
if(a.len!=b.len)return 0;
for(int i=0;i<a.len;i++)if(a.a[i]!=b.a[i])return 0;
return 1;
}
bool operator<(const bint &a,const bint &b){
if(a.len!=b.len)return a.len<b.len;
for(int i=a.len-1;i>=0;i--)if(a.a[i]!=b.a[i])return a.a[i]<b.a[i];
return 0;
}
bint operator+(const bint &a,const bint &b){
bint c;
c.len=max(a.len,b.len);
for(int i=0;i<c.len;i++)c.a[i]+=a.a[i]+b.a[i],c.a[i+1]+=c.a[i]/10,c.a[i]%=10;
if(c.a[c.len])c.len++;
return c;
}
bint operator*(const bint &a,const bint &b){
static cn x[maxn+10],y[maxn+10],z[maxn+10];
int n=a.len+b.len;
int t=0;
while((1<<t)<n)t++;
n=1<<t;
for(int i=0;i<n;i++)x[i]=cn(a.a[i],0),y[i]=cn(b.a[i],0);
fft(x,t,n,1);
fft(y,t,n,1);
for(int i=0;i<n;i++)z[i]=x[i]*y[i];
fft(z,t,n,-1);
bint c;
c.len=a.len+b.len-1;
for(int i=0;i<c.len;i++)c.a[i]+=z[i].a+0.5,c.a[i+1]+=c.a[i]/10,c.a[i]%=10;
if(c.a[c.len])c.len++;
return c;
}
bint operator-(const bint &a,const bint &b){
bint c;
for(int i=0;i<a.len;i++){
c.a[i]+=a.a[i]-b.a[i];
if(c.a[i]<0)c.a[i]+=10,c.a[i+1]--;
}
c.len=a.len;
while(c.len&&!c.a[c.len-1])c.len--;
return c;
}
bint n,ni;
int fac;
//预处理n的倒数
void init(){
ni=1;
fac=n.len;
int lim=n.len<<1;
for(int i=1;i<=100;i++){
bint two;
two.len=fac+1;
two.a[fac]=2;
ni=ni*(two-n*ni);
fac*=2;
if(ni.len>lim){
fac-=ni.len-lim;
ni.clear(lim);
}
}
}
void mod(bint &a){
bint q=a*ni;
q.clear(q.len-fac);
a=a-q*n;
while(a==n||n<a)
a=a-n;
}
int main(){
n=431923;
bint a=54812353;
init();
mod(a);
a.print();
}
压位高精度
以后有时间填坑……
参考代码:「来自大佬【bearThinking】,码风已修改。」
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char s[255];
constexpr auto maxn=1000000000;
class _int
{
public:
int n,x[25];
_int(){n=0,memset(x,0,sizeof(x));}
_int(int a){n=1,memset(x,0,sizeof(x)),x[0]=a;}
friend void read(_int &a)
{
scanf("%s",s);
int t=strlen(s);
a.n=(t+8)/9;
for(int i=0;i<a.n;++i)
{
for(int j=max(t-9,0);j<t;++j) a.x[i]=a.x[i]*10+(s[j]^48);
t-=9;
}
}
friend void write(const _int &a)
{
if(!a.n){puts("0");return;}
printf("%d",a.x[a.n-1]);
for(int i=a.n-2;i>=0;--i) printf("%09d",a.x[i]);
putchar('\n');
}
friend _int operator +(const _int &a,const _int &b)
{
_int c;c.n=max(a.n,b.n);
for(int i=0;i<c.n;++i)
{
c.x[i]+=a.x[i]+b.x[i];
c.x[i]<maxn?0:(c.x[i]-=maxn,c.x[i+1]++);
}
if(c.x[c.n]) c.n++;
return c;
}
friend _int operator -(const _int &a,const _int &b)
{
_int c=a;
for(int i=0;i<c.n;++i)
{
c.x[i]-=b.x[i];
c.x[i]<0?(c.x[i]+=maxn,c.x[i+1]--):0;
}
while(c.n&&!c.x[c.n-1]) c.n--;
return c;
}
friend int operator %(_int a,const int &b)
{
int c=0;
for(int i=a.n-1;~i;--i) c=(1ll*maxn*c+a.x[i])%b;
return c;
}
friend bool operator <(const _int &a,const _int &b)
{
if(a.n^b.n) return a.n<b.n;
for(int i=a.n-1;~i;--i) if(a.x[i]^b.x[i]) return a.x[i]<b.x[i];
return false;
}
friend bool operator >(const _int &a,const _int &b)
{
if(a.n^b.n) return a.n>b.n;
for(int i=a.n-1;~i;--i) if(a.x[i]^b.x[i]) return a.x[i]>b.x[i];
return false;
}
};
signed main()
{
_int a,b;
read(a),read(b),write(a+b);
return 0;
}
参考博客:
高精度幂小技巧「来自 WC」
#include<iostream>
#include<cmath>
//头文件iomanip中包含了setiosflags与setprecision,也可以用fixed代替setiosflags(ios::fixed)
using namespace std;
int main()
{
int n;
cin>>n;
cout.precision(n>0?0:-n);//cout.precision()是控制浮点数的输出精度的(四舍五入保留几位小数)
cout<<fixed<<pow(2.0L,n)<<endl;//cout<<fixed表示按一般方式输出小数,而非科学计数法
return 0;
}
//可计算2的-16383~16383次方
\(2\) 可以改为任意整数。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
stringstream ss;
ss.precision(0);
ss<<fixed<<pow(2.0L,n);
string s=ss.str();
s[s.length()-1]--;
cout<<s<<endl;
return 0;
}
//计算2的n次方-1
//n最大可以为16383
要将 \(2\) 改为其他整数就比较麻烦,因为要考虑减 \(1\) 后的借位,要用高精减单精。
附
- 感谢 fys 学长的补充,像以 \(10\) 为底数这样的特殊情况还是有规律可循的~

浙公网安备 33010602011771号