|
高精度,用一个线性表保存一个大整数,具体说,将大整数写成p进制数,线性表的每一项存p进制其中一位。 参考下面代码 #include <iostream>' W) N/ ^: V# v5 ?4 A5 x0 U
#include <memory>" k. U9 [ A( G' U
# include <string>$ ?( m' m! e, Q0 ] z
using namespace std; typedef long long hugeint; const int Base = 1000000000; B4 G* `( O1 K8 N
const int Capacity = 200; struct xnum
( S" o1 M; D# g{
+ M- U! D$ d% `/ ?) J8 i int Len;" L0 V8 R: F5 K
int Data[Capacity];
0 ?% y9 d5 I) t# L' U+ ?% Z6 K xnum() : Len(0) {}
( z& X/ Y2 C" H- G# y xnum(const xnum& V) : Len(V.Len) { memcpy(Data, V.Data, Len * sizeof *Data); }
: C/ z3 o5 o0 i8 Z xnum(int V) : Len(0) { for (; V > 0; V /= Base) Data[Len++] = V % Base; }
& ?% C5 O* O/ E2 P- K: h1 P- o xnum& operator=(const xnum& V) { Len = V.Len; memcpy(Data, V.Data, Len * sizeof *Data); return *this; }8 J( a0 n" e. M- |& z& O O1 `, r
int& operator[](int Index) { return Data[Index]; }
b2 ]4 @0 T$ z: L! _+ O int operator[](int Index) const { return Data[Index]; }, M* {; y( X. C% c- P- }
};
6 m, ~- y) E: h0 xint compare(const xnum& A, const xnum& B)
4 L5 s7 F% Q- d{
3 o6 F% M" o' @ A int I;, u7 I) j" G5 _" {) d& ~# Q3 K
if (A.Len != B.Len) return A.Len > B.Len ? 1 : -1;8 p& S5 L& b a! R' s
for (I = A.Len - 1; I >= 0 && A[I] == B[I]; I--);
) a/ T2 M' N$ K. A5 q. G. K2 E if (I < 0) return 0;
" I# |9 t( d7 t return A[I] > B[I] ? 1 : -1;
3 n+ r, G( m9 `. ?} xnum operator+(const xnum& A, const xnum& B)' `: Q( ~7 S) u
{
, m ~+ p8 ~4 t/ }. U" z; w% U7 Z! D xnum R;+ f- G# A0 p* L+ Y4 B1 U4 h
int I;
/ K, R) T' P' f. Z( Z' I, c% G int Carry = 0;
; b2 p* y2 o: J C; c2 S+ u+ y" X for (I = 0; I < A.Len || I < B.Len || Carry > 0; I++)
( t) s9 L4 r e( V {
/ a" L' B. t/ L if (I < A.Len) Carry += A[I];5 p% l0 X2 _ w1 v. T1 P* A
if (I < B.Len) Carry += B[I];
5 P6 p+ g6 b T! W D$ b R[I] = Carry % Base;
" Z8 J" m ]) y2 ^, L( s0 ~! f Carry /= Base;: U" ]% J. `) ]
}+ \+ ^! o3 Z$ E7 _9 G0 Z# |3 g
R.Len = I;7 n; I3 p* G& e# m
return R;4 O" f5 B# D# w5 R( A+ M
} xnum operator-(const xnum& A, const xnum& B)# ?# r0 u, l6 W2 i) u4 v3 o
{
' Q$ @; j7 D' O x& A5 O, N6 b xnum R;
6 B& }7 ]1 y/ g& a int Carry = 0;4 t2 D- T9 a7 V# |6 h
R.Len = A.Len;
9 T3 O* d1 f, g; o2 x int I;
. g0 A3 h* P" J& C for (I = 0; I < R.Len; I++)1 o( O" P% m6 e- F( f! h9 U' ?
{
2 F% N- D8 k$ M: C, D @% a# O8 r R[I] = A[I] - Carry;6 U1 \# U2 P! o4 X5 J) H0 Z# b
if (I < B.Len) R[I] -= B[I];
8 M4 G, d* D% {" ]- B1 C/ [ d if (R[I] < 0) Carry = 1, R[I] += Base;) [3 s2 }. g8 r- ~4 V, C4 y
else Carry = 0;1 ^; H4 q9 _# L) a: M
}
3 R0 ]+ a7 \4 Z% e while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;
' R. v7 N5 z0 a% e9 g3 u- R return R;
0 T9 q5 _, `' j# T} xnum operator*(const xnum& A, const int B)8 w# i0 G6 w. O8 ~! O& e
{8 c9 ^& P# M" r! x! T1 t" H6 q
int I;4 k4 P9 o* U# [! ~, e0 |: A
if (B == 0) return 0;
! C8 }) Y. v& ` xnum R;
; F2 q d8 C4 `' Z' Z0 @3 k hugeint Carry = 0;
! } y% K6 U6 ^" N, f; Y0 o for (I = 0; I < A.Len || Carry > 0; I++)
* P) \) M+ _% f3 A3 ?! V {
7 A! W h+ r3 Z2 ` if (I < A.Len) Carry += hugeint(A[I]) * B;
; |+ _: {4 X2 P, N$ L) f R[I] = Carry % Base;
& M" J, m H4 T' F" o# \% F) ? Carry /= Base;3 o/ |9 E Y( u1 a
}. M! j! V+ b0 n1 w
R.Len = I;
/ i0 Y% ~: V8 Q! C, I. p7 u/ T return R;
$ C4 q% C# M9 N} xnum operator*(const xnum& A, const xnum& B)
6 J' P6 E; X# O2 [( H+ t2 O{$ B8 K) L( c+ Q. U5 X9 W
int I;/ B; I6 L' p( |9 e
if (B.Len == 0) return 0;6 n Q( J# }, q. ^, V$ Z
xnum R;& {, }% x, M4 V& J
for (I = 0; I < A.Len; I++)
) j5 w0 R ^0 |6 U {
/ A/ H( s3 R2 z hugeint Carry = 0;1 ]6 q8 O6 K* h0 [% Q
for (int J = 0; J < B.Len || Carry > 0; J++)) O( x9 ^" v$ P0 m6 t: ~- P; W9 ?
{: \$ m* |$ W3 M: P( K3 S
if (J < B.Len) Carry += hugeint(A[I]) * B[J];, k2 A* P( S* i; f$ B
if (I + J < R.Len) Carry += R[I + J];
5 F8 I5 H& c$ Y if (I + J >= R.Len) R[R.Len++] = Carry % Base;# u: v7 `" p2 P3 o5 x' b2 Q
else R[I + J] = Carry % Base;
/ ?% P+ P7 _, H: U Carry /= Base;
& n+ z/ B, W9 t. s } $ p0 P; o& l9 W6 }/ e
}2 p% m9 A, @$ e8 W! K, j
return R;
. H/ H! o! T8 f$ t6 S} xnum operator/(const xnum& A, const int B)
* D; g$ |9 ~: [5 u* \{
% C* n( \1 p+ D& ~9 ] xnum R;
Z4 ?% C& R) p. y6 u9 W8 U int I;( b1 V+ O6 }8 U3 q2 n# n
hugeint C = 0;
, H2 @4 m6 u* i for (I = A.Len - 1; I >= 0; I--)( ]9 R* W8 n9 E$ P/ ]7 w- J+ p) u, E
{
* H+ j; X4 F, X4 d0 {9 O( F. f! s9 m C = C * Base + A[I];3 X9 C( i( N) O+ L+ g! Z7 S! p
R[I] = C / B;
* Q: g) E) b" }% p C %= B;
- J, B! E- z: p6 m4 \2 s: Q: E- R }; g; t9 K5 E7 K
R.Len = A.Len;
, f- i2 u* b1 Y- {% L& H while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;
$ B6 i' d/ _- q$ I. [+ G. N return R;
6 J, c+ C/ m5 I} xnum operator/(const xnum& A, const xnum& B)) g8 {: S9 w; E
{% @1 q% f1 v: |9 C/ s3 @
int I;0 @% ]' z5 l8 q
xnum R, Carry = 0;
. [1 F# z9 M: z int Left, Right, Mid;
; K& M5 a. b" |' Z" l% r for (I = A.Len - 1; I >= 0; I--)! Z( Q, o6 q/ |
{
! M. p7 H7 ]% y8 Q# X; p Carry = Carry * Base + A[I];) Z: B* t0 O. o4 [2 z
Left = 0;
) q0 h6 z4 x1 f0 M% | Right = Base - 1;
/ {0 m6 o+ u, Y, z1 a while (Left < Right)2 ]+ v, q( _* e; j
{7 l3 E7 }+ S0 K1 {- h
Mid = (Left + Right + 1) / 2;" E5 j! m0 O- m6 ~! z+ [
if (compare(B * Mid, Carry) <= 0) Left = Mid;' z# s7 @; _' a/ |
else Right = Mid - 1;; \+ |3 h1 ?8 j* G4 ?/ h) a, S
} `8 z5 d1 t6 X: m3 Z& Z
R[I] = Left;$ B/ R! w' J) W+ E
Carry = Carry - B * Left;
: O/ g# u* D5 U4 B }
! ]: ~( F6 e) ]% ?. A# v, a R.Len = A.Len;
, ^8 |# O/ O1 X- Y7 [ while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;
# Y4 W% m$ M: l3 } return R;4 G0 ~, l6 `& T/ T1 X
}
C3 E" Z, Y5 k- W3 X, F- c8 j1 Z [xnum operator%(const xnum& A, const xnum& B)/ S. H2 o1 e( c5 B0 {
{
" h) q( Z1 K/ Q/ k int I;
" C! o1 C* W( f" t ~0 Q xnum R, Carry = 0;" n" ^& H$ } P; G- M: [1 s+ Y/ r
int Left, Right, Mid;
1 P' M0 M! a# F# v for (I = A.Len - 1; I >= 0; I--)
7 J- [7 |. x3 q2 b$ Q5 H% S {, A) i( d8 Z) j- @+ c5 R! Q
Carry = Carry * Base + A[I];4 g& Q6 b8 e( o% q* b" c4 E
Left = 0;+ I$ J' z! T" R
Right = Base - 1;3 L2 a/ ?# {/ N( [" l0 D! ]8 c
while (Left < Right)3 K _" ~1 |; x+ w& J
{8 ~% d- H5 j. z8 l2 @. }
Mid = (Left + Right + 1) / 2;& e# N5 K x( ]
if (compare(B * Mid, Carry) <= 0) Left = Mid;$ r/ V8 p+ W, E8 E: Y+ t" s5 F! F+ E
else Right = Mid - 1; M5 I# h) V4 O. ^
}
1 w! ~5 s( D. b8 z$ ] R[I] = Left;
- ]0 i+ X/ a! u' N7 l2 P9 ?+ s Carry = Carry - B * Left;" j# I! [) ~5 s5 k/ y& z( j1 e( B
}
0 D( x# q: g- G) z7 k8 \, z$ x R.Len = A.Len;
- t$ i* k- O" X! |3 O while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;$ F1 @4 K# s; b; ~+ L
return Carry;
1 v0 `# z% }: o1 E6 Z* `* y8 C* J} istream& operator>>(istream& In, xnum& V). d8 n+ ]! _. E/ N. j* B
{
7 J4 U0 M' P% f5 Y( S8 D char Ch;$ C/ z4 f/ B. a
for (V = 0; In >> Ch;)
2 W: V0 a* s7 z+ D2 E9 V {& }" T; d; l* P! t( {+ u
V = V * 10 + (Ch - '0');- z4 h' Z4 r+ o+ w9 ]
if (cin.peek() <= ' ') break;" T% G3 k5 U6 u4 K
}# E( J; P% t1 o% h" V: G! u. O
return In;6 C9 g4 W8 O6 A2 r3 q3 H) M5 s
} ostream& operator<<(ostream& Out, const xnum& V)% ^0 P. d4 R: Y2 \1 O7 P
{* ?/ Z" z5 y) I+ S' i' M
int I;* s7 P9 U! [* x+ g- c0 y
Out << (V.Len == 0 ? 0 : V[V.Len - 1]);' T; a B. O5 Y& }& g4 |: \
for (I = V.Len - 2; I >= 0; I--) for (int J = Base / 10; J > 0; J /= 10) Out << V[I] / J % 10;
% f3 r5 `" T6 e return Out;
/ Q2 C% Y x( n7 E# E* Y}
5 Z! d: j- B4 S9 A3 H; [( n |