1. 程式人生 > >【模板】【數論】高精度

【模板】【數論】高精度

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cmath>

#define re register

using namespace std;

const int MAXN = 10003;
const int base = 10000;

struct Bigint{
    int num[MAXN];
    int len,sign;
    Bigint() {memset
(num,0,sizeof(num)); len=1; sign=1;} Bigint operator = (const char *s) { int l=strlen(s); int k=1; len=1; for(re int i=1;i<=l;i++) { if(k==base) k=1,++len; num[len]+=(s[l-i]-'0')*k; k=k*10; } return
*this; } Bigint operator = (const int &x) { char s[MAXN]; sprintf(s,"%d",x); *this=s; return *this; } bool operator < (const Bigint &x) const { bool flag=0; if(sign==-1&&x.sign==1) return true; if(sign==1
&&x.sign==-1) return false; if(sign==-1&&x.sign==-1) flag=1; if(len!=x.len) return len<x.len; for(re int i=len;i>=1;i--) if(num[i]!=x.num[i]) return flag?x.num[i]<num[i]:num[i]<x.num[i]; return false; } bool operator > (const Bigint &x) const {return x<*this;} bool operator <= (const Bigint &x) const {return !(*this>x);} bool operator >= (const Bigint &x) const {return !(*this<x);} bool operator == (const Bigint &x) const {return !(*this<x)&&!(*this>x);} bool operator != (const Bigint &x) const {return !(*this==x);} Bigint operator + (const Bigint &b) const { Bigint c; c.len=max(len,b.len); for(re int i=1;i<=c.len;i++) { c.num[i]+=num[i]+b.num[i]; if(c.num[i]>=base) c.num[i]-=base,++c.num[i+1]; } if(c.num[c.len+1]) ++c.len; return c; } Bigint operator += (const Bigint &b) { return *this=*this+b; } Bigint operator + (const int &x) { Bigint b; b=x; return *this+b; } Bigint operator += (const int &b) { return *this=*this+b; } Bigint operator ++ (int b) { return *this+=1; } Bigint operator - (const Bigint &x) const//一定要加const!因為有swap操作! { Bigint a,b,c; a=*this;b=x; c.len=max(a.len,b.len); if(*this<b) swap(a,b),c.sign=-1; for(re int i=1;i<=c.len;i++) { c.num[i]+=a.num[i]-b.num[i]; if(c.num[i]<0) c.num[i]+=base,--c.num[i+1]; } while(!c.num[c.len]&&c.len>1) --c.len; return c; } Bigint operator -= (const Bigint &b) { return *this=*this-b; } Bigint operator - (const int &x) { Bigint b; b=x; return *this-b; } Bigint operator -= (const int &b) { return *this=*this-b; } Bigint operator -- (int b) { return *this-=1; } Bigint operator * (const int &b) const { Bigint c; c.len=len+1; for(re int i=1;i<=len;i++) { c.num[i]+=num[i]*b; c.num[i+1]=c.num[i]/base; c.num[i]%=base; } while(!c.num[c.len]&&c.len>1) --c.len; return c; } Bigint operator * (const Bigint &b) const { Bigint c; if(*this+b==*this||*this+b==b) return c; c.len=len+b.len; for(re int i=1;i<=len;i++) for(re int j=1;j<=b.len;j++) { c.num[i+j-1]+=num[i]*b.num[j]; c.num[i+j]+=c.num[i+j-1]/base; c.num[i+j-1]%=base; } while(!c.num[c.len]&&c.len>1) --c.len; return c; } Bigint operator *= (const Bigint &b) { return *this=*this*b; } Bigint operator / (const int &b) const { Bigint c; c.len=len; int x=0; for(re int i=c.len;i>=1;i--) { c.num[i]+=(x*base+num[i])/b; x=(x*base+num[i])%b; } while(!c.num[c.len]&&c.len>1) --c.len; return c; } int operator % (const int &b) const { int ans=0; for(re int i=1;i<=len;i++) ans=(ans*10+num[i])%b; return ans; } Bigint operator %= (const int &b) { return *this=*this%b; } Bigint Copy(const Bigint &a,int x)//從高位開始擷取長度為x的子段 { Bigint t; t.len=a.len+x-1; for(int i=1;i<=a.len;i++) t.num[i+x-1]=a.num[i]; while(!t.num[t.len]&&t.len>1) --t.len; return t; } //模擬豎式 高精除 Bigint Div1(const Bigint &a,const Bigint &b,Bigint &mod) { Bigint c; c.len=a.len-b.len+1; mod=a; for(int i=c.len;i>=1;i--) { Bigint t; t=Copy(b,i); while(mod>=t) { c.num[i]++; mod-=t; } } while(!c.num[c.len]&&c.len>0) --c.len; return c; } //倍增 模擬豎式 高精除 Bigint Div2(const Bigint &a,const Bigint &b,Bigint &mod) { Bigint c; c.len=a.len-b.len+1; mod=a; int pw[20]; pw[0]=1; for(int i=1;i<=15;i++) pw[i]=pw[i-1]<<1;//預處理倍增陣列(2^k) for(int i=c.len;i>=1;i--) { Bigint t; t=Copy(b,i); for(int j=15;j>=0;j--) if(mod>=t*pw[j]) { c.num[i]+=pw[j]; mod-=t*pw[j]; } } while(!c.num[c.len]&&c.len>1) --c.len; return c; } Bigint operator / (const Bigint &b) { Bigint c; if(*this<b) return c; return Div2(*this,b,c); } Bigint operator % (const Bigint &b) { if(*this<b) return *this; Bigint c; Div2(*this,b,c); return c; } /* //二分高精除,基於高精乘,高精除單精 O(len^2*loglen) Bigint operator / (const Bigint &b) { Bigint l,r,mid; if(*this<b) return l; r=*this; while(l<r) { mid=(l+r)/2; if(mid*b<*this) l=mid+1; else r=mid; } if(l*b>*this) l--; return l; } Bigint operator % (const Bigint &b) { return *this-(*this/b)*b; } */ Bigint operator %= (const Bigint &b) { return *this=*this%b; } inline void read() { char s[MAXN]; scanf("%s",s); *this=s; } inline void write() { if(sign==-1) putchar('-'); printf("%d",num[len]); for(re int i=len-1;i>=1;i--) printf("%04d",num[i]); putchar('\n'); } }; Bigint a,b; int main() { a.read(); b.read(); (a+b).write(); (a-b).write(); (a*b).write(); (a/b).write(); (a%b).write(); return 0; }