【模板】高精度

  1 namespace BigNumber{
  2     const int L=5010,Base=10000,Bit=4;
  3     const LL MaxInt=2147483647;
  4     const int Pw10[15]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
  5     const int Pw2[20]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536};
  6          
  7     LL DOF[L];
  8          
  9     struct BigNum{
 10         int v[L],le,flag;
 11         BigNum(){
 12             memset(v,0,sizeof v); le=flag=1;
 13         }
 14         BigNum(int x){
 15             flag=1; le=1; memset(v,0,sizeof v);
 16             if (x<0) flag=-1,x=-x;
 17             v[1]=x;
 18             while (v[le]>=Base) v[le+1]+=v[le]/Base,v[le]%=Base,++le;
 19         }
 20         BigNum(LL x){
 21             flag=1; le=1; memset(v,0,sizeof v);
 22             if (x<0) flag=-1,x=-x;
 23             v[1]=x%Base; v[2]=x/Base%Base;
 24             v[3]=x/Base/Base%Base; v[4]=x/Base/Base/Base;
 25             le=4;
 26             while (v[le]>=Base) v[le+1]+=v[le]/Base,v[le]%=Base,++le;
 27             while (v[le]==0 && le>1) --le;
 28         }
 29         BigNum(int len,int fir){
 30             memset(v,0,sizeof v);
 31             le=len; v[le]=fir; flag=1;
 32         }
 33         BigNum(const BigNum &a,int x){
 34             memset(v,0,sizeof v);
 35             le=a.le+x; flag=a.flag;
 36             for (int i=1;i<=a.le;++i) v[i+x]=a.v[i];
 37         }
 38         int IntoInt(){
 39             if (le>3) cerr <<"Error: cannot change so big into int!"<<endl;
 40             LL d=0;
 41             for (int i=le;i>=1;--i) d=d*Base+v[i];
 42             if (flag==-1) d=-d;
 43             if (d>MaxInt || -d<MaxInt+1) cerr <<"Error: cannot change so big into int!"<<endl;
 44             return d;
 45         }
 46              
 47         void Clear(){
 48             memset(v,0,sizeof v); le=flag=1;
 49         }
 50         void Tidy() {
 51             if (le == 1 && !v[le]) flag = 1;
 52             return;
 53         }
 54         void operator =(int a){
 55             *this = BigNum(a);
 56         }
 57         void operator =(LL a){
 58             *this = BigNum(a);
 59         }
 60              
 61              
 62         //Compare -->
 63         bool operator ==(const BigNum &a)const{
 64             if (le!=a.le || flag!=a.flag) return 0;
 65             for (int i=1;i<=le;++i) if (v[i]!=a.v[i]) return 0;
 66             return 1;
 67         }
 68         bool operator <(const BigNum &a)const{
 69             if (flag < a.flag) return 1;
 70             if (flag > a.flag) return 0;
 71             if (le < a.le) return flag == 1 ? 1 : 0;
 72             if (le > a.le) return flag == 1 ? 0 : 1;
 73             for (int i=le;i>=1;--i){
 74                 if (v[i]<a.v[i]) return flag==1? 1:0;
 75                 if (v[i]>a.v[i]) return flag==1? 0:1;
 76             }return 0;
 77         }
 78         bool operator >(const BigNum &a)const{
 79             if (flag < a.flag) return 0;
 80             if (flag > a.flag) return 1;
 81             if (le < a.le) return flag == 1 ? 0 : 1;
 82             if (le > a.le) return flag == 1 ? 1 : 0;
 83             for (int i=le;i>=1;--i){
 84                 if (v[i]<a.v[i]) return flag==1? 0:1;
 85                 if (v[i]>a.v[i]) return flag==1? 1:0;
 86             }return 0;
 87         }
 88         bool operator ==(const int &x)const{
 89             return *this == BigNum(x);
 90         }
 91              
 92              
 93         //Add and Sub -->
 94         void operator +=(const BigNum &x){
 95             BigNum a=*this; BigNum b=x; memset(v,0,sizeof v);
 96             flag=1;
 97             if (a.flag==-1 && b.flag==-1){
 98                 flag=-1; a.flag=1; b.flag=1;
 99             }
100             if (a < b) swap(a,b);
101             if (b.flag==-1){
102                 b.flag=1;
103                 if (a < b) swap(a,b),flag=-1;
104                 b.flag=-1;
105             }
106             if (b.flag==1){
107                 le=a.le;
108                 for (int i=1;i<=le;++i) v[i]=a.v[i]+b.v[i];
109                 for (int i=1;i<=le;++i) v[i+1]+=v[i]/Base,v[i]%=Base;
110                 while (v[le+1]>0) ++le;
111             }else{
112                 le=a.le;
113                 for (int i=1;i<=le;++i) v[i]=a.v[i]-b.v[i];
114                 for (int i=1;i<=le;++i) if (v[i]<0) --v[i+1],v[i]+=Base;
115                 while (v[le]==0 && le>1) --le;
116             }
117         }
118         void operator +=(int x){
119             *this += BigNum(x);
120         }
121         void operator -=(const BigNum &x){
122             BigNum a=x; a.flag=-a.flag;
123             *this += a;
124         }
125         void operator -=(int x){
126             *this -= BigNum(x);
127         }
128              
129              
130         BigNum &operator ++(){
131             return *this += 1, *this;
132         }
133         BigNum &operator --(){
134             return *this -= 1, *this;
135         }
136         BigNum operator ++(int){
137             BigNum c(*this);
138             ++ *this; return c;
139         }
140         BigNum operator --(int){
141             BigNum c(*this);
142             -- *this; return c;
143         }
144              
145              
146         //Mul -->
147         void operator *=(const BigNum &x){
148             BigNum a=x;
149             if (flag==a.flag) flag=1;else flag=-1;
150             a.flag=1;
151                  
152             memset(DOF,0,sizeof DOF);
153             for (int i=1;i<=le;++i)
154                 for (int j=1;j<=a.le;++j)
155                     DOF[i+j-1]+=v[i]*a.v[j];
156             le+=a.le+9;
157             for (int i=1; i<=le; ++i) v[i]=0;
158             for (int i=1;i<=le;++i) DOF[i+1]+=DOF[i]/Base,DOF[i]%=Base;
159             while (DOF[le]==0 && le>1) --le;
160             for (int i=1;i<=le;++i) v[i]=DOF[i];
161         }
162         void operator *=(const int &x){
163             *this *= BigNum(x);
164         }
165         void operator *=(const LL &x){
166             *this *= BigNum(x);
167         }
168              
169              
170         //Div -->
171         void operator /=(int x){
172             if (x==0){
173                 cerr <<"Error: div 0!"; return;
174             }
175             BigNum a; a=x;
176             if (flag==a.flag) flag=1;else flag=-1;
177             a.flag=1;
178             if (x < 0) x = -x;
179              
180             memset(DOF,0,sizeof DOF);
181             LL rest=0;
182             for (int i=le;i>=1;--i){
183                 rest=rest*Base+v[i];
184                 DOF[i]=rest/x; rest%=x;
185                 v[i]=0;
186             }
187             for (int i=le;i>=1;--i) v[i]=DOF[i];
188             while (v[le]==0 && le>1) --le;
189         }
190         void operator /=(const BigNum &x){
191             if (x==0){
192                 cerr <<"Error: div 0!"; return;
193             }
194             BigNum a=*this,b=x,c,d;
195             if (a.flag==b.flag) flag=1;else flag=-1;
196             a.flag = b.flag = 1;
197             for (int i=le;i>0;--i) v[i]=0;
198             le=a.le-b.le+1;
199              
200             for (int i=le;i>=1;--i){
201                 c=BigNum(b,i-1);
202                 for (int j=log2(Base);j>=0;--j){
203                     d=c; d*=Pw2[j];
204                     if (!(a < d)) v[i]+=Pw2[j],a-=d;
205                 }
206             }
207             for (int i=1;i<=le;++i) v[i+1]+=v[i]/Base,v[i]%=Base;
208             while (v[le+1]>0) ++le;
209             while (v[le]==0 && le>1) --le;
210         }
211              
212              
213         //Mod -->
214         void operator %=(int p){
215             if (p==0){
216                 cerr <<"Error: mod 0!"; return;
217             }
218             LL d=0; if (p < 0) p=-p;
219             for (int i=le;i>=1;--i) d=(d*Base+v[i])%p,v[i]=0;
220             le=1; v[1]=d;
221             while (v[le]>=Base) v[le+1]+=v[le]/Base,v[le]%=Base,++le;
222         }
223              
224         void operator %=(const BigNum &x){
225             if (x==0){
226                 cerr <<"Error: mod 0!"; return;
227             }
228             BigNum a=*this,b=x,c,d;
229             for (int i=le;i>0;--i) v[i]=0;
230             le=a.le-b.le+1;
231                  
232             for (int i=le;i>=1;--i){
233                 c=BigNum(b,i-1);
234                 for (int j=log2(Base);j>=0;--j){
235                     d=c; d*=Pw2[j];
236                     if (!(a < d)) a-=d;
237                 }
238             }
239             *this = a;
240         }
241              
242              
243         //Power -->
244         BigNum pow(int b){
245             BigNum a,c; a=*this; c=1;
246             for (;b;b>>=1,a*=a) if (b&1) c*=a;
247             return c;
248         }
249         BigNum pow(int x,int b){
250             BigNum c,a; c=1; a=x;
251             for (;b;b>>=1,a*=a) if (b&1) c*=a;
252             return c;
253         }
254         int pow2(int a,int b){
255             int c=1;
256             for (;b;b>>=1,a*=a) if (b&1) c*=a;
257             return c;
258         }
259              
260              
261         //Shr and Shl -->
262         void operator <<=(int x){
263             if (x<=30) *this *= pow2(2,x);
264                 else *this *= pow(2,x);
265         }
266         void operator >>=(int x){
267             if (x<=30) *this /= pow2(2,x);
268                 else *this /= pow(2,x);
269         }
270  
271          
272         void rev() {
273             if (le > 1 || v[le]) flag = -flag;
274             return;
275         }
276          
277     };
278          
279          
280     //Compare -->
281     bool operator ==(const int &a,const BigNum &b){
282         return b == a;
283     }
284     bool operator !=(const BigNum &a,const BigNum &b){
285         return !(a == b);
286     }
287     bool operator !=(const BigNum &a,const int &b){
288         return !(a == b);
289     }
290     bool operator !=(const int &a,const BigNum &b){
291         return !(b == a);
292     }
293          
294          
295     bool operator <(const BigNum &a,const int &b){
296         return a < BigNum(b);
297     }
298     bool operator <(const int &a,const BigNum &b){
299         return BigNum(a) < b;
300     }
301     bool operator >(const BigNum &a,const int &b){
302         return a > BigNum(b);
303     }
304     bool operator >(const int &a,const BigNum &b){
305         return BigNum(a) > b;
306     }
307     bool operator <=(const BigNum &a,const BigNum &b){
308         if (a > b) return 0; return 1;
309     }
310     bool operator >=(const BigNum &a,const BigNum &b){
311         if (a < b) return 0; return 1;
312     }
313     bool operator <=(const BigNum &a,const int &b){
314         if (a > b) return 0; return 1;
315     }
316     bool operator <=(const int &a,const BigNum &b){
317         if (a > b) return 0; return 1;
318     }
319     bool operator >=(const BigNum &a,const int &b){
320         if (a < b) return 0; return 1;
321     }
322     bool operator >=(const int &a,const BigNum &b){
323         if (a < b) return 0; return 1;
324     }
325          
326          
327     int max(const int &a,const int &b){
328         if (a < b) return b; return a;
329     }
330     int min(const int &a,const int &b){
331         if (a < b) return a; return b;
332     }
333     BigNum max(const BigNum &a,const BigNum &b){
334         if (a < b) return b; return a;
335     }
336     BigNum min(const BigNum &a,const BigNum &b){
337         if (a < b) return a; return b;
338     }
339          
340          
341     //Add -->
342     BigNum operator +(const BigNum &a,const BigNum &b){
343         BigNum c=a; c+=b; return c;
344     }
345     BigNum operator +(const BigNum &a,const int &b){
346         BigNum c=a; c+=b; return c;
347     }
348     BigNum operator +(const int &a,const BigNum &b){
349         BigNum c=b; c+=a; return c;
350     }
351          
352          
353     //Sub -->
354     BigNum operator -(const BigNum &a,const BigNum &b){
355         BigNum c=a; c-=b; return c;
356     }
357     BigNum operator -(const BigNum &a,const int &b){
358         BigNum c=a; c-=b; return c;
359     }
360     BigNum operator -(const int &a,const BigNum &b){
361         BigNum c=b; c-=a; return c;
362     }
363          
364          
365     //Mul -->
366     BigNum operator *(const BigNum &a,const BigNum &b){
367         BigNum c=a; c*=b; return c;
368     }
369     BigNum operator *(const BigNum &a,const int &b){
370         BigNum c=a; c*=b; return c;
371     }
372     BigNum operator *(const int &a,const BigNum &b){
373         BigNum c=b; c*=a; return c;
374     }
375          
376          
377     //Div -->
378     BigNum operator /(const BigNum &a,const int &b){
379         BigNum c=a; c/=b; return c;
380     }
381     BigNum operator /(const int &a,const BigNum &b){
382         BigNum c=b; c/=a; return c;
383     }
384     BigNum operator /(const BigNum &a,const BigNum &b){
385         BigNum c=a; c/=b; return c;
386     }
387          
388          
389     //Mod -->
390     BigNum operator %(const BigNum &a,const int &b){
391         BigNum c=a; c%=b; return c;
392     }
393     BigNum operator %(const int &a,const BigNum &b){
394         BigNum c=b; c%=a; return c;
395     }
396     BigNum operator %(const BigNum &a,const BigNum &b){
397         BigNum c=a; c%=b; return c;
398     }
399          
400     //Shr and Shl -->
401     BigNum operator <<(const BigNum &a,const int b){
402         BigNum c=a; c<<=b; return c;
403     }
404     BigNum operator <<(const BigNum &a,BigNum &b){
405         return a << b.IntoInt();
406     }
407     BigNum operator >>(const BigNum &a,const int &b){
408         BigNum c=a; c>>=b; return c;
409     }
410     BigNum operator >>(const BigNum &a,BigNum &b){
411         return a >> b.IntoInt();
412     }
413  
414          
415     //Abs -->
416     BigNum abs(const BigNum &x){
417         BigNum c=x; c.flag=1; return c;
418     }
419          
420          
421     //Odd -->
422     int odd(const BigNum &x){
423         if (x.v[1] & 1) return 1; return 0;
424     }
425          
426          
427     //Gcd -->
428     BigNum gcd(const BigNum &x,const BigNum &y){
429         if (x.le == 1 && !x.v[1]) return y;
430         if (y.le == 1 && !y.v[1]) return x;
431         BigNum a=x,b=y,c=BigNum(1);
432         while (a!=b){
433             if (a < b) swap(a,b);
434             if (odd(a) && odd(b)) a-=b; else
435             if (odd(a)) b/=2; else
436             if (odd(b)) a/=2; else
437                 a/=2,b/=2,c*=2;
438         }return a*c;
439     }
440          
441          
442     //Sqrt -->
443     BigNum sqrt(const BigNum &x){
444         if (x<0){
445             cerr <<"Error: sqrt nagetive!";
446             return 0;
447         }
448         BigNum l,r,m,A;
449         l=BigNum(x.le/2,1); r=BigNum(x.le/2+2,1);
450         while (l<=r){
451             m=(l+r)>>1;
452             if (m*m<=x) A=m,l=m+1; else r=m-1;
453         }return A;
454     }
455     BigNum sqrt(const BigNum &a,int b){
456         BigNum x=a;
457         if (x<0 && b%2==0){
458             cerr <<"Error: sqrt nagetive!";
459             return 0;
460         }
461         BigNum l,r,m,A;
462         int frog=x.flag; x.flag=1;
463         l=0; r=1;
464         while (r.pow(b)<x) l=r,r*=2;
465         while (l<=r){
466             m=(l+r)>>1;
467             if (m.pow(b)<=x) A=m,l=m+1; else r=m-1;
468         }
469         if (frog==-1) A.flag=-1;
470         return A;
471     }
472          
473          
474     //Read and Print -->
475     string yz; char cyz;
476     void Read(BigNum &a){
477         a.Clear();
478         while (cin.peek()==' ') getchar();
479         if (cin.peek()=='-'){
480             a.flag=-1; cin >>cyz;
481         }
482         cin >>yz;
483         int len=yz.length();
484         a.le=len/Bit;
485         for (int i=1;i<=a.le;++i){
486             int l=len-Bit*i,r=l+Bit-1;
487             for (int j=l;j<=r;++j) a.v[i]=a.v[i]*10+yz[j]-'0';
488         }
489         if(len%Bit!=0){
490             int r=len-Bit*a.le-1;
491             ++a.le;
492             for (int j=0;j<=r;++j) a.v[a.le]=a.v[a.le]*10+yz[j]-'0';
493         }
494     }
495          
496     void PrintWith(int x,int k){
497         for (int i=k-1;i>=0;--i) if (Pw10[i]>x) putchar('0');
498             else putchar(x/Pw10[i]+'0'),x%=Pw10[i];
499     }
500     void Print(const BigNum &a){
501         if (a.flag==-1 && (a.le > 1 || a.v[a.le])) putchar('-');
502         printf("%d",a.v[a.le]);
503         for (int i=a.le-1;i>=1;--i) PrintWith(a.v[i],Bit);
504     }
505     void Println(const BigNum &a){
506         Print(a); puts("");
507     }
508 };
509  
510 using namespace BigNumber;

 

posted @ 2018-03-23 20:36  Dance_Of_Faith  阅读(182)  评论(0编辑  收藏  举报