大数据高精度模版:
加法和乘法(修改进行优化,并弄清原理)
struct BigInt
{
const static int mod = 10000;
const static int DLEN = 4;
int a[maxn],len;
BigInt()
{
memset(a,0,sizeof(a));
len=1;
}
BigInt(int v)
{
memset(a,0,sizeof(a));
len=0;
do{
a[len++] =v%mod;
v /= mod;
}while(v);
}
BigInt(const char s[])
{
memset(a,0,sizeof(a));
int L=strlen(s);
len=L/DLEN;
if(L%DLEN)len++;
int index=0;
for(int i=L-1;i>=0;i=i-DLEN)
{
int t=0;
int k=i-DLEN+1;
if(k<0)k=0;
for(int j=k;j<=i;j++)
t=t*10+s[j]-'0';
a[index++]=t;
}
}
BigInt operator +(const BigInt &b)const
{
BigInt res;
res.len=max(len,b.len);
for(int i=0;i<=res.len;i++)
res.a[i]=0;
for(int i=0;i<res.len;i++)
{
res.a[i]+=((i<len)?a[i]:0)+((i<b.len)?b.a[i]:0);
res.a[i+1]+=res.a[i]/mod;
res.a[i]%=mod;
}
if(res.a[res.len]>0)res.len++;
return res;
}
BigInt operator *(const BigInt &b)const
{
BigInt res;
for(int i=0;i<len;i++)
{
int up=0;
for(int j=0;j<b.len;j++)
{
int temp=a[i]*b.a[j]+res.a[i+j]+up;
res.a[i+j]=temp%mod;
up=temp/mod;
}
if(up!=0)
res.a[i+b.len]=up;
}
res.len=len+b.len;
while(res.a[res.len-1]==0&&res.len>1)
res.len--;
return res;
}
void output()
{
printf("%d",a[len-1]);
for(int i = len-2; i >=0 ; i--)
printf("%04d",a[i]);
printf("\n");
}
};
其他模版
#define DLEN 4
class BigNumber
{
private:
int a[1000];
int len;
public:
BigNumber();
BigNumber(int);
BigNumber(const char*);
BigNumber(const BigNumber &);
BigNumber & operator = (const BigNumber &);
BigNumber operator + (const BigNumber &) const;
BigNumber operator - (const BigNumber &) const;
BigNumber operator * (const BigNumber &) const;
BigNumber operator / (const int &) const;
BigNumber operator ^ (const int &) const;
int operator % (const int &) const;
bool operator > (const int &) const;
bool operator < (const int &) const;
bool operator == (const int &) const;
bool operator > (const BigNumber &T) const;
bool operator < (const BigNumber &T) const;
bool operator == (const BigNumber &T) const;
void Print();
};
BigNumber::BigNumber()
{
len=1;
memset(a,0,sizeof(a));
}
BigNumber::BigNumber(int b)
{
len=0;
memset(a,0,sizeof(a));
do{
a[len++]=b%mod;
b=b/mod;
}while(b);
}
BigNumber::BigNumber(const char *s)
{
memset(a,0,sizeof(a));
int l=strlen(s);
len=0;
for(int i=l-1;i>=0;i=i-DLEN)
{
int k=i-DLEN+1;
if(k<0)k=0;
for(int j=k;j<=i;j++)
a[len]=a[len]*10+s[j]-'0';
len++;
}
while(len>1 && a[len-1]==0)len--;
}
BigNumber::BigNumber(const BigNumber &T):len(T.len)
{
memset(a,0,sizeof(a));
for(int i=0;i<len;i++)a[i]=T.a[i];
}
BigNumber &BigNumber::operator = (const BigNumber &T)
{
len=T.len;
memset(a,0,sizeof(a));
for(int i=0;i<len;i++)a[i]=T.a[i];
return *this;
}
BigNumber BigNumber::operator + (const BigNumber &T) const
{
BigNumber t(*this);
int bigger=T.len>len?T.len:len;
for(int i=0;i<bigger;i++)
{
t.a[i]=t.a[i]+T.a[i];
if(t.a[i]>=mod)
{
t.a[i+1]++;
t.a[i]=t.a[i]-mod;
}
if(t.a[bigger]!=0)t.len=bigger+1;
else t.len=bigger;
}
return t;
}
BigNumber BigNumber::operator - (const BigNumber &T) const
{
bool flag;
BigNumber t1,t2;
if(*this>T)
{
t1=*this;
t2=T;
flag=0;
}
else
{
t1=T;
t2=*this;
flag=1;
}
int bigger=t1.len;
for(int i=0;i<bigger;i++)
{
if(t1.a[i]<t2.a[i])
{
int j=i+1;
while(t1.a[j]==0)j++;
t1.a[j--]--;
while(j>i)t1.a[j--]+=mod-1;
t1.a[i]+=mod-t2.a[i];
}
else t1.a[i]=t1.a[i]-t2.a[i];
}
t1.len=bigger;
while(t1.a[t1.len-1]==0 && t1.len>1)
{
t1.len--;
bigger--;
}
if(flag)t1.a[bigger-1]=0-t1.a[bigger-1];
return t1;
}
BigNumber BigNumber::operator * (const BigNumber &T) const
{
BigNumber ret;
for(int i=0;i<len;i++)
{
int up=0;
for(int j=0;j<T.len;j++)
{
int temp=a[i]*T.a[j]+ret.a[i+j]+up;
if(temp>=mod)
{
up=temp/mod;
ret.a[i+j]=temp-(temp/mod)*mod;
}
else
{
up=0;
ret.a[i+j]=temp;
}
}
if(up!=0)ret.a[i+T.len]=up;
}
ret.len=len+T.len;
while(ret.a[ret.len-1]==0 && ret.len>1)ret.len--;
return ret;
}
BigNumber BigNumber::operator /(const int &q) const
{
BigNumber ret;
int down=0;
for(int i=len-1;i>=0;i--)
{
ret.a[i]=(a[i]+down*mod)/q;
down=a[i]+down*mod-ret.a[i]*q;
}
ret.len=len;
while(ret.len>1 && ret.a[ret.len-1]==0)ret.len--;
return ret;
}
int BigNumber::operator %(const int &b)const
{
int r=0;
for(int i=len-1;i>=0;i--)r=(r*mod%b+a[i])%b;
return r;
}
bool BigNumber::operator > (const int &t)const
{
BigNumber b(t);
return *this>b;
}
bool BigNumber::operator < (const int &t)const
{
BigNumber b(t);
return *this<b;
}
bool BigNumber::operator == (const int &t)const
{
BigNumber b(t);
return *this==b;
}
bool BigNumber::operator > (const BigNumber &T)const
{
if(len>T.len)return true;
if(len<T.len)return false;
int ln=len-1;
while(a[ln]==T.a[ln] && ln>0)ln--;
if(ln>=0 && a[ln]>T.a[ln])return true;
else return false;
}
bool BigNumber::operator < (const BigNumber &T)const
{
if(len<T.len)return true;
if(len>T.len)return false;
int ln=len-1;
while(a[ln]==T.a[ln] && ln>0)ln--;
if(ln>=0 && a[ln]<T.a[ln])return true;
else return false;
}
bool BigNumber::operator == (const BigNumber &T)const
{
if(len==T.len)
{
int ln=len-1;
while(a[ln]==T.a[ln] && ln>=0)ln--;
if(ln<0) return true;
}
return false;
}
void BigNumber::Print()
{
printf("%d",a[len-1]);
for(int i=len-2;i>=0;i--)
printf("%04d",a[i]);
printf("\n");
}
简化模版
#define DLEN 4
struct BigNumber
{
int a[1000];
int len;
BigNumber(){len=1;memset(a,0,sizeof(a));}
BigNumber(int b)
{
len=0;
memset(a,0,sizeof(a));
do{
a[len++]=b%mod;
b=b/mod;
}while(b);
}
BigNumber(char* s)
{
memset(a,0,sizeof(a));
int l=strlen(s);
len=0;
for(int i=l-1;i>=0;i=i-DLEN)
{
int k=i-DLEN+1;
if(k<0)k=0;
for(int j=k;j<=i;j++)
a[len]=a[len]*10+s[j]-'0';
len++;
}
while(len>1 && a[len-1]==0)len--;
}
BigNumber(BigNumber &b)
{
len=b.len;
memset(a,0,sizeof(a));
for(int i=0;i<len;i++)a[i]=b.a[i];
}
BigNumber & operator =(const BigNumber &b)
{
len=b.len;
memset(a,0,sizeof(a));
for(int i=0;i<len;i++)a[i]=b.a[i];
return *this;
}
BigNumber operator +(BigNumber &b)
{
BigNumber ans;
ans.len=max(len,b.len);
int add=0;
for(int i=0;i<ans.len;i++)
{
ans.a[i]=a[i]+b.a[i]+add;
if(ans.a[i]>=mod)
{
add=1;
ans.a[i]=ans.a[i]-mod;
}
else
add=0;
}
if(add==1) ans.a[ans.len++]=1;
return ans;
}
BigNumber operator *(BigNumber &b)
{
BigNumber ans;
for(int i=0;i<len;i++)
{
int up=0;
for(int j=0;j<b.len;j++)
{
int temp=a[i]*b.a[j]+ans.a[i+j]+up;
if(temp>=mod)
{
up=temp/mod;
ans.a[i+j]=temp-(temp/mod)*mod;
}
else
{
up=0;
ans.a[i+j]=temp;
}
}
if(up!=0)ans.a[i+b.len]=up;
}
ans.len=len+b.len;
while(ans.len>1 && ans.a[ans.len-1]==0&&ans.len>1)ans.len--;
return ans;
}
BigNumber operator /(int b)
{
BigNumber ans;
int down=0;
for(int i=len-1;i>=0;i--)
{
ans.a[i]=(a[i]+down*mod)/b;
down=down*mod+a[i]-ans.a[i]*b;
}
ans.len=len;
while(ans.len>1 && ans.a[ans.len-1]==0)ans.len--;
return ans;
}
int operator %(int b)
{
int r=0;
for(int i=len-1;i>=0;i--)r=(r*mod+a[i])%b;
return r;
}
bool operator <(BigNumber &b)
{
if(len<b.len) return true;
if(len>b.len) return false;
int i=len-1;
while(i>=0 && a[i]==b.a[i])i--;
if(i>=0 && a[i]<b.a[i]) return true;
return false;
}
bool operator ==(BigNumber &b)
{
if(len!=b.len)return false;
int i=len-1;
while(i>=0 && a[i]==b.a[i])i--;
if(i<0) return true;
return false;
}
bool operator !=(BigNumber &b)
{
if(*this==b)return false;
return true;
}
void Print()
{
printf("%d",a[len-1]);
for(int i=len-2;i>=0;i--)printf("%04d",a[i]);
printf("\n");
}
};
快速傅里叶变换 FFT
void fft(cp *a,int inv)
{
int bit=0;
while ((1<<bit)<n)bit++;
fo(i,0,n-1)
{
rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
if (i<rev[i])swap(a[i],a[rev[i]]);//不加这条if会交换两次(就是没交换)
}
for (int mid=1;mid<n;mid*=2)//mid是准备合并序列的长度的二分之一
{
cp temp(cos(pi/mid),inv*sin(pi/mid));//单位根,pi的系数2已经约掉了
for (int i=0;i<n;i+=mid*2)//mid*2是准备合并序列的长度,i是合并到了哪一位
{
cp omega(1,0);
for (int j=0;j<mid;j++,omega*=temp)//只扫左半部分,得到右半部分的答案
{
cp x=a[i+j],y=omega*a[i+j+mid];
a[i+j]=x+y,a[i+j+mid]=x-y;//这个就是蝴蝶变换什么的
}
}
}
}
分数运算
struct frac
{
ll top,low;
frac(){}
frac(ll t,ll l){top=t;low=l;}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
frac operator+(frac b)
{
frac c(top*b.low+low*b.top,low*b.low);
ll g=gcd(c.top,c.low);
c.top=c.top/g,c.low=c.low/g;
return c;
}
frac operator*(frac b)
{
frac c(top*b.top,low*b.low);
ll g=gcd(c.top,c.low);
c.top=c.top/g,c.low=c.low/g;
return c;
}
};