大数
发布时间:2020-12-14 03:03:38 所属栏目:大数据 来源:网络整理
导读:const int maxl = 25;const int bitlen = 4;char buffer[maxl * bitlen + 10];const int MAXL = 10000;LL tmp[bitlen * maxl];LL q[bitlen * maxl];struct Bignum{ int a[maxl]; int sz; bool read() { memset(a,sizeof(a)); sz = 0; if (scanf("%s",buffer)
const int maxl = 25; const int bitlen = 4; char buffer[maxl * bitlen + 10]; const int MAXL = 10000; LL tmp[bitlen * maxl]; LL q[bitlen * maxl]; struct Bignum { int a[maxl]; int sz; bool read() { memset(a,sizeof(a)); sz = 0; if (scanf("%s",buffer) != 1) return false; int n = strlen(buffer); int i; for (i = n - 1; i >= 0; i -= bitlen) { LL x = 0,y = 1; for (int j = i; j > i - bitlen && j >= 0; --j) { x += y*(buffer[j] - '0'); y *= 10; } a[sz++] = x; } return true; } Bignum() { memset(a,sizeof(a)); sz = 0; } Bignum(LL x) { memset(a,sizeof(a)); sz = 0; if (x == 0) sz = 1; while (x != 0) { a[sz++] = x % MAXL; x /= MAXL; } } Bignum(const Bignum&bg) { sz = bg.sz; memset(a,sizeof(a)); for (int i = 0; i < sz; ++i) a[i] = bg.a[i]; } int cmp(const Bignum&bg) const { if (sz>bg.sz) return 1; else if (sz < bg.sz) return -1; for (int i = sz-1; i >= 0; --i) if (a[i] < bg.a[i]) return -1; else if (a[i]>bg.a[i]) return 1; return 0; } bool operator<(const Bignum&bg) const { return cmp(bg) < 0; } bool operator==(const Bignum&bg) const { return cmp(bg) == 0; } bool operator<=(const Bignum&bg) const { return cmp(bg) <= 0; } bool operator>(const Bignum&bg) const { return cmp(bg)>0; } bool operator>=(const Bignum&bg) const { return cmp(bg) >= 0; } bool operator!=(const Bignum&bg) const { return cmp(bg) != 0; } Bignum operator=(const Bignum&bg) { sz = bg.sz; memset(a,sizeof(a)); for (int i = 0; i < sz; ++i) a[i] = bg.a[i]; return *this; } void add(const Bignum&bg) { sz = max(sz,bg.sz); for (int i = 0; i < sz; ++i) { a[i] += bg.a[i]; a[i + 1] += a[i] / MAXL; a[i] %= MAXL; } while (a[sz] != 0) ++sz; } Bignum operator+(const Bignum&bg) { if (bg == 0) return *this; Bignum ret = *this; ret.add(bg); return ret; } void sub(const Bignum&small) { for (int i = 0; i < sz; ++i) { a[i] -= small.a[i]; if (a[i] < 0) { int j = i + 1; a[i] += MAXL; while (--a[j]<0) { a[j] += MAXL; ++j; } } } while (sz>1 && a[sz - 1] == 0) --sz; } void mul(const Bignum&b) { memset(tmp,sizeof(tmp)); for(int i=0;i<sz;++i) { for(int j=0;j<b.sz;++j) { tmp[i+j]+=a[i]*b.a[j]; tmp[i+j+1]+=tmp[i+j]/MAXL; tmp[i+j]%=MAXL; } } sz+=b.sz; while(tmp[sz]>0) { tmp[sz+1]+=tmp[sz]/MAXL; tmp[sz]%=MAXL; ++sz; } while(sz>1&&tmp[sz-1]==0) --sz; for(int i=0;i<sz;++i) a[i]=tmp[i]; } Bignum operator-(const Bignum&small) { if (small == 0) return *this; int cp = cmp(small); if (cp == 0) return 0; Bignum A = *this,B = small; A.sub(B); return A; } Bignum operator/(LL x) { Bignum ret = *this; LL y = 0; for (int i = sz - 1; i >= 0; --i) { y = y*MAXL + ret.a[i]; ret.a[i] = y / x,y %= x; } while (ret.sz > 1 && ret.a[ret.sz - 1] == 0) --ret.sz; return ret; } LL operator%(LL x) { LL y = 0; for (int i = sz - 1; i >= 0; --i) { y = y*MAXL + a[i]; if (y >= x) y %= x; } return y; } Bignum operator*(const Bignum&bg) { Bignum ret=*this; ret.mul(bg); return ret; } Bignum pow(LL x) { Bignum ret = 1,base = *this; while (x) { if (x & 1) ret = ret*base; base = base*base; x >>= 1; } return ret; } Bignum operator*(LL x) { return *this*Bignum(x); } bool Try_sub(char *s,char *t,int lent,int lens) { if(lent>lens) return false; for(int i=0;i<lens;++i) q[i]=s[i]; bool ok=true; for(int i=0;i<lens;++i) { s[i]-=t[i]; if(s[i]>=0) continue; int j=i+1; s[i] += 10; while (j<lens && --s[j]<0) { s[j] += 10; ++j; } if(j>=lens) { ok=false; break; } } if(ok) return true; for(int i=0;i<lens;++i) s[i]=q[i]; return false; } Bignum operator/(const Bignum&bg) { int cp=cmp(bg); if(cp==0) return 1; else if(cp<0) return 0; char * s= new char[bitlen*sz+5],*t=new char [bitlen*sz+5]; char * ans= new char [bitlen*sz+5]; int lens=0,lent=0; s[lens]=t[lent]=0; for(int i=0;i<sz;++i) { int x=a[i]; for(int j=0;j<4;++j) { s[lens++]=x%10; s[lens]=0; x/=10; } x=bg.a[i]; for(int j=0;j<4;++j) { t[lent++]=x%10; t[lent]=0; x/=10; } } while(lent>1 && t[lent-1]==0) --lent; while(lens>1 && s[lens-1]==0) --lens; for(int i=lent;i<lens;++i) t[i]=0; for(int i=lens-1;i>=0;--i) { ans[i]=0; while(Try_sub(s+i,t,lent,lens-i)) ++ans[i]; } for(int i=lens;i<=lens+4;++i) ans[i]=0; Bignum ret; for(int i=0;i<lens;i+=4) { ret.a[i/4]=1000*ans[i+3]+100*ans[i+2]+10*ans[i+1]+ans[i]; } ret.sz=sz; while(ret.sz>1 && ret.a[ret.sz-1]==0) --ret.sz; delete [] s; delete [] t; delete [] ans; return ret; } Bignum operator%(const Bignum&bg) { if (bg == 0) return 0; Bignum ret = *this; ret = (ret / bg)*bg; return *this - ret; } void output() const { printf("%d",a[sz - 1]); for (int i = sz - 2; i >= 0; --i) printf("%04d",a[i]); printf("n"); } }; 第二版:压9位的大数 typedef long long LL; const int maxl = 50; const int bitlen = 9; char buffer[maxl * bitlen + 10]; const int MAXL = 1000000000; //10^9 LL tmp[bitlen * maxl]; LL q[bitlen * maxl]; typedef unsigned long long u_long; struct Bignum { int a[maxl]; int sz; bool read(); Bignum() { memset(a,sizeof(a)); sz = 1; } Bignum(u_long x); Bignum(const Bignum&); int cmp(const Bignum&bg) const; bool operator<(const Bignum&bg) const { return cmp(bg) < 0; } bool operator==(const Bignum&bg) const { return cmp(bg) == 0; } bool operator<=(const Bignum&bg) const { return cmp(bg) <= 0; } bool operator>(const Bignum&bg) const { return cmp(bg)>0; } bool operator>=(const Bignum&bg) const { return cmp(bg) >= 0; } bool operator!=(const Bignum&bg) const { return cmp(bg) != 0; } bool Try_sub(char *s,int lens); Bignum& operator = (const Bignum&bg); Bignum& operator += (const Bignum&bg); Bignum & operator -= (const Bignum& bg); Bignum& operator *= (const Bignum& bg); Bignum& operator /= (const Bignum& bg); Bignum& operator /= (int x); int operator % (int x); Bignum operator + (const Bignum&bg) const { return Bignum(*this) += bg; } Bignum operator / (const Bignum& bg) const { return Bignum(*this) /= bg; } Bignum operator * (const Bignum& bg) const { return Bignum(*this) *= bg; } Bignum operator - (const Bignum&bg) const { return Bignum(*this) -= bg; } Bignum operator%(const Bignum&bg) const { return *this - *this / bg * bg; } Bignum operator / (int x) const { return Bignum(*this) /= x; } Bignum pow(LL x); void output() const { printf("%d",a[sz - 1]); for (int i = sz - 2; i >= 0; --i) printf("%09d",a[i]); printf("r"); } }; bool Bignum::read() { memset(a,sizeof(a)); sz = 0; if (scanf("%s",buffer) != 1) return false; int n = strlen(buffer); int i; for (i = n - 1; i >= 0; i -= bitlen) { u_long x = 0,y = 1; for (int j = i; j > i - bitlen && j >= 0; --j) { x += y * (buffer[j] - '0'); y *= 10; } a[sz++] = x; } return true; } Bignum::Bignum(u_long x) { memset(a,sizeof(a)); sz = 0; if (x == 0) sz = 1; while (x != 0) { a[sz++] = x % MAXL; x /= MAXL; } } Bignum::Bignum(const Bignum& bg) { sz = bg.sz; memcpy(a,bg.a,sizeof(a)); } int Bignum::cmp(const Bignum&bg) const { if (sz>bg.sz) return 1; else if (sz < bg.sz) return -1; for (int i = sz-1; i >= 0; --i) if (a[i] < bg.a[i]) return -1; else if (a[i] > bg.a[i]) return 1; return 0; } Bignum& Bignum::operator=(const Bignum& bg) { sz = bg.sz; memcpy(a,sizeof(a)); return *this; } Bignum& Bignum::operator += (const Bignum& bg) { sz = max(sz,bg.sz); for (int i = 0; i < sz; ++i) { a[i] += bg.a[i]; a[i + 1] += a[i] / MAXL; a[i] %= MAXL; } while (a[sz] != 0) ++sz; return *this; } Bignum& Bignum::operator -= (const Bignum& bg) { for (int i = 0; i < sz; ++i) { a[i] -= bg.a[i]; if (a[i] < 0) { int j = i + 1; a[i] += MAXL; while (--a[j]<0) { a[j] += MAXL; ++j; } } } while (sz>1 && a[sz - 1] == 0) --sz; return *this; } Bignum& Bignum::operator*=(const Bignum& b) { memset(tmp,sizeof(tmp)); u_long w = 0; for(int i=0;i<sz;++i) if (a[i]) { for(int j=0;j<b.sz;++j) if (b.a[j]) { int k = i + j; w = (u_long) a[i] * b.a[j]; while (w > 0) { w += tmp[k]; tmp[k++] = w % MAXL; w /= MAXL; } } } sz+=b.sz; w = 0; while(tmp[sz]>0) { w += (u_long) tmp[sz]; tmp[sz] = w % MAXL; w /= MAXL; ++sz; } while(sz>1&&tmp[sz-1]==0) --sz; for(int i=0;i<sz;++i) a[i] = tmp[i]; return *this; } Bignum& Bignum::operator /= (int x) { u_long y = 0; for (int i = sz - 1; i >= 0; --i) { y = y * MAXL + a[i]; a[i] = y / x,y %= x; } while (sz > 1 && a[sz - 1] == 0) --sz; return *this; } int Bignum::operator % (int x) { u_long y = 0; for (int i = sz - 1; i >= 0; --i) { y = y*MAXL + a[i]; if (y >= x) y %= x; } return y; } Bignum Bignum::pow(LL x) { Bignum ret = 1,base = *this; while (x) { if (x & 1) ret = ret * base; base = base * base; x >>= 1; } return ret; } bool Bignum::Try_sub(char * s,char * t,int lens) { if(lent>lens) return false; for(int i=0;i<lens;++i) q[i]=s[i]; bool ok=true; for(int i=0;i<lens;++i) { s[i]-=t[i]; if(s[i]>=0) continue; int j=i+1; s[i] += 10; while (j<lens && --s[j]<0) { s[j] += 10; ++j; } if(j>=lens) { ok=false; break; } } if(ok) return true; for(int i=0;i<lens;++i) s[i]=q[i]; return false; } Bignum& Bignum::operator /= (const Bignum& bg) { int cp=cmp(bg); if(cp==0) return *this = 1; else if(cp<0) return *this = 0; char * s= new char[bitlen*(sz+2)],*t=new char [bitlen*(sz+2)]; char * ans= new char [bitlen*(sz+2)]; int lens=0,lent=0; s[lens]=t[lent]=0; for(int i=0;i<sz;++i) { int x=a[i]; for(int j=0;j<bitlen;++j) { s[lens++]=x%10; s[lens]=0; x/=10; } x=bg.a[i]; for(int j=0;j<bitlen;++j) { t[lent++]=x%10; t[lent]=0; x/=10; } } while(lent>1 && t[lent-1]==0) --lent; while(lens>1 && s[lens-1]==0) --lens; for(int i=lent;i<lens;++i) t[i]=0; for(int i=lens-1;i>=0;--i) { ans[i]=0; while(Try_sub(s+i,lens-i)) ++ans[i]; } for(int i=lens;i<=lens+bitlen;++i) ans[i]=0; for(int i=0;i<lens;i+=bitlen) { u_long x = 1; a[i/bitlen] = 0; for(int j = 0; j < bitlen; ++j) { a[i/bitlen] += x * ans[j+i]; x *= 10; } } while(sz>1 && a[sz-1]==0) --sz; delete [] s; delete [] t; delete [] ans; return *this; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |