|
高精度,用一个线性表保存一个大整数,具体说,将大整数写成p进制数,线性表的每一项存p进制其中一位。 参考下面代码 #include <iostream>, v% A. P9 n- \7 A1 O3 J$ c6 x6 |. o0 S9 L
#include <memory>
2 o! N$ j7 }+ F# d1 v- [# include <string>( ?& c& Q, V& u$ z. q
using namespace std; typedef long long hugeint; const int Base = 1000000000;
3 R2 b/ p) r" y, y0 dconst int Capacity = 200; struct xnum
5 t) l2 o( j9 _: C, `{
* P+ s2 q& p" w int Len;' D: H9 R7 T! e. E5 D* e+ I
int Data[Capacity];# H" ^" m: G0 S0 e3 }/ W7 p* V
xnum() : Len(0) {}" F+ `6 n; Y% k1 P" O' L
xnum(const xnum& V) : Len(V.Len) { memcpy(Data, V.Data, Len * sizeof *Data); }
9 t. l6 c8 X; Q* ` P6 t xnum(int V) : Len(0) { for (; V > 0; V /= Base) Data[Len++] = V % Base; }
8 ?! c9 a( x7 }7 i: }) r9 U xnum& operator=(const xnum& V) { Len = V.Len; memcpy(Data, V.Data, Len * sizeof *Data); return *this; }
5 K; c9 p+ B# n \! S int& operator[](int Index) { return Data[Index]; }( a2 ]7 R6 { k) C/ h: [3 Y
int operator[](int Index) const { return Data[Index]; }
6 J _1 W4 f8 g$ j/ P" P}; ) q: @/ ~2 u9 e0 i& ^- F
int compare(const xnum& A, const xnum& B)$ @( b/ l" A/ h/ z1 U4 f
{
6 X" ]) s$ h& t7 j int I;" P$ j7 Z7 d$ J7 D# V2 ?
if (A.Len != B.Len) return A.Len > B.Len ? 1 : -1;/ p+ I7 l; P4 U7 } `
for (I = A.Len - 1; I >= 0 && A[I] == B[I]; I--);1 g: w5 F2 |8 ~2 W' V8 y
if (I < 0) return 0;
9 T$ d, F0 F% u return A[I] > B[I] ? 1 : -1;0 p" E0 L0 ]' G8 _. u
} xnum operator+(const xnum& A, const xnum& B)/ k( {1 U3 m/ k! J
{
, y) M1 W- U: Q2 g6 C" e xnum R;
5 I2 l, `/ B0 U! V& P' m int I;8 Z# _; c) i4 b0 E
int Carry = 0;
" [8 ^0 o% H* `* G' r: M6 ] for (I = 0; I < A.Len || I < B.Len || Carry > 0; I++)9 V, B# C8 c: }# V$ `
{
* ]/ `, K) U: ~, k& k if (I < A.Len) Carry += A[I];1 R8 g) D' y5 [3 g) M
if (I < B.Len) Carry += B[I];
. U) m( `6 E6 Z: D+ I R[I] = Carry % Base;! M+ F* U; t7 m' U
Carry /= Base;$ \3 c* ?: ~; Q ~7 i7 ]/ I
}
0 Q: @9 b6 [( @9 g* g R.Len = I;/ u) O) m5 w e; a! ]
return R;
+ s0 A) Z- `5 a+ ] `} xnum operator-(const xnum& A, const xnum& B)
, W4 ~; t2 e$ M. Q{$ b) P9 j) K/ X% `
xnum R;+ d( D# j8 z0 r
int Carry = 0;
; g7 ?) a! }$ O, c" h0 F% o3 [; \ R.Len = A.Len;
0 H* |, |4 y/ s, `5 w4 H7 q ` [+ z int I;2 Z( M: i$ ]6 i
for (I = 0; I < R.Len; I++)
, S. ~% V" z/ G" {5 T+ C/ h2 ` {
& d# k( ?% ?4 W) s' k; c* w2 @) l R[I] = A[I] - Carry;
, }) W: n- J7 a8 c4 J7 J4 Q if (I < B.Len) R[I] -= B[I];* y* T3 P5 d- I
if (R[I] < 0) Carry = 1, R[I] += Base;, p p) J8 O* B7 y6 k9 |% ]% X
else Carry = 0;; Q& }5 K, x- ?6 A* X' Z- W" a
}
8 ?9 y" R2 y2 t while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;0 v; D7 W! b* c
return R;
/ l; M& G3 j! r} xnum operator*(const xnum& A, const int B); S/ t8 M; O7 j0 T; E# X+ ^) r7 I
{
, q( i7 ^% P: J8 ?% k7 m. z int I;
) D, h' \; g8 g6 t if (B == 0) return 0;+ Z4 z2 R L7 j8 w: F
xnum R;0 B8 M, W/ J& |6 y) P5 b
hugeint Carry = 0; M8 G1 E8 C- C% h
for (I = 0; I < A.Len || Carry > 0; I++)
9 y+ ?0 x5 p' ]; d# u {8 ^; y3 S$ [$ z3 W
if (I < A.Len) Carry += hugeint(A[I]) * B;
- h$ Z1 d1 j8 c9 D* W R[I] = Carry % Base;
$ @2 C/ b S* X. X& | Carry /= Base;
( M* { B3 O0 h2 h- x; N }
# {3 S+ [+ H6 J4 @* H( m5 f9 _ R.Len = I;7 x% M* {; y5 f0 ?2 }. t
return R;; b2 p# A* d) f; X ]8 `- _
} xnum operator*(const xnum& A, const xnum& B)0 @# ~0 k" z& R5 A
{7 C- J& ]9 W+ L
int I;
; w% ]8 U, i: K if (B.Len == 0) return 0;
d( H: w0 M$ `* i7 l$ G xnum R;
2 W V% V& J$ P1 Q) J for (I = 0; I < A.Len; I++)9 v1 V; r: @% \
{
& t+ W7 [5 r( f& f. h hugeint Carry = 0;; b$ }8 `" i( w0 U1 R) O4 L
for (int J = 0; J < B.Len || Carry > 0; J++), Y1 v* \& m v) s% w% u R6 Y* ~
{
+ j* _ B: L2 C. U7 J if (J < B.Len) Carry += hugeint(A[I]) * B[J];
0 }! p# J) A/ t0 z) S if (I + J < R.Len) Carry += R[I + J];
7 S& A( h8 C$ u) {( B j* P if (I + J >= R.Len) R[R.Len++] = Carry % Base;
' Y2 d: E5 [5 Q' _# m: K( Y else R[I + J] = Carry % Base;8 ?" X: O0 L& b! C K2 X7 m- H T
Carry /= Base;
9 O+ Y) M: t2 T5 D }
1 j/ N$ }! J( R. ^: q( H }
0 Z) c: \: n ^- d return R;# [" t$ D5 r: P1 L, d& h% P
} xnum operator/(const xnum& A, const int B)1 j& i9 U0 K8 W7 K& M
{" _8 @5 O/ p- \$ _
xnum R;- z6 [6 a# z1 G3 P" O
int I;) ^/ H4 E7 Q; D& q. ^
hugeint C = 0;
! C7 V, ~' Y$ T# |3 Q5 a9 x [ for (I = A.Len - 1; I >= 0; I--)
7 r& Z) l, d0 G/ q0 L {4 w9 n X' u) s% O5 v* k
C = C * Base + A[I];
C2 u1 \/ X6 @" Z R[I] = C / B;
% `( ^: i3 v* g2 e N C %= B;
E R4 Z( y& N( D }
: e* i% S; q. m& m h R.Len = A.Len;. o- K" _5 l" S# d
while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;$ T# J" K7 ]2 k0 Z/ V$ J
return R;
8 v% E! n5 K8 T+ e& c} xnum operator/(const xnum& A, const xnum& B)
8 y9 ]6 Q/ }8 h6 I# m5 C" j4 ~+ [{. m# b4 e/ j( D5 S
int I;9 y$ Q6 i6 f( t" R3 o# k
xnum R, Carry = 0;! C: O% G7 c* e2 R
int Left, Right, Mid;8 c2 o& v9 W8 A
for (I = A.Len - 1; I >= 0; I--)
, h' ^% Q, k0 m7 N& D! o {) S; U. p$ @" r: O3 n. w
Carry = Carry * Base + A[I]; q& Y# F0 m7 k& g# L g
Left = 0;% m% j$ ]1 I- C+ O! r( E: \9 [
Right = Base - 1;% G- u8 R& R n+ C% k8 c; ~
while (Left < Right)% U' w% U: I0 k, S: j) k7 {# T4 l
{( L, x$ b' G% h* z7 B
Mid = (Left + Right + 1) / 2;3 ?! D# k9 t5 u3 g0 Y
if (compare(B * Mid, Carry) <= 0) Left = Mid; ?$ t; l* B$ o
else Right = Mid - 1;
. _5 X9 S6 q! m: k1 h- M. K }& l$ \" f3 V3 U2 Z0 [4 U
R[I] = Left;
" P' E1 W1 c* U' b. _5 S, _ Carry = Carry - B * Left;
T6 d4 ?+ s( }* A, r! z3 g, k }
+ J \5 i, |6 {6 P% C% m' Z R.Len = A.Len;
4 k, z v0 [) b- t. R while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;8 k S, Q+ M" ^. ^9 h4 g
return R;; {: K, X7 K2 u
}& @+ f4 ?5 u1 x5 l
xnum operator%(const xnum& A, const xnum& B)$ {) z! m7 a, j0 S
{7 I3 F. U9 O9 P
int I;
) ?2 U8 Y9 X+ t W E xnum R, Carry = 0;
) u5 v: z5 t0 q& C9 I- M int Left, Right, Mid;
( s; ~# a" g2 o2 U% q9 b) ]" s for (I = A.Len - 1; I >= 0; I--)
3 z7 Q% w: a* S; v: v {3 E* n* d& r; h) P
Carry = Carry * Base + A[I];
7 m5 }0 \4 E) G \9 u Left = 0;2 x* l4 i, a: I: X: X; G) W
Right = Base - 1;3 W0 n6 @2 K2 k4 ?, y* R9 g, S1 I
while (Left < Right)
. a% P) D# D n# F6 q& }5 D {
) h% v! x' ]" a5 S Mid = (Left + Right + 1) / 2;
8 U' Z4 d$ V9 Y if (compare(B * Mid, Carry) <= 0) Left = Mid;
/ w* W4 C& g1 L( I/ ?; O else Right = Mid - 1;
; I0 V G6 c. x* Y g/ R) J }
$ p- j# @8 U7 c2 u, w, g# e" A R[I] = Left;$ [* ^! z4 S$ z* \1 i0 ^' _8 P
Carry = Carry - B * Left;
2 I3 N! ]# B6 j' h }+ Y" S- G: m( l0 \3 }: p
R.Len = A.Len;
X* ~$ N! y8 g$ \5 M/ R% B$ N' ~ while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;6 T5 W5 t; ^5 y6 \) O0 M
return Carry;' c8 u$ _, A C" j: t
} istream& operator>>(istream& In, xnum& V)
6 A1 l6 H y$ t/ C{/ h6 a+ m: F! i- G5 R8 _" p( p' d
char Ch;
$ o O# P2 x5 r5 L. m for (V = 0; In >> Ch;): J! S. p+ Y5 W7 S) X0 W. ~
{
0 H8 c' M# }2 W7 t* E* k V = V * 10 + (Ch - '0');8 i' ]' c3 _. D( ~2 U# S, e! P
if (cin.peek() <= ' ') break;
& D5 Y% c# \0 W+ Z6 ^. y% g3 ~, `5 W }- c1 p% |: T) S
return In;
- ?; [" G9 {9 u& x/ j* J0 m} ostream& operator<<(ostream& Out, const xnum& V)
8 p4 G# O9 d' m0 O% e1 `{/ Z+ z8 w2 k4 O% y
int I;; }1 K4 ]; m, t% ^. X z' Y# E! e
Out << (V.Len == 0 ? 0 : V[V.Len - 1]);7 r9 W! E7 N# J. u& x+ o# B
for (I = V.Len - 2; I >= 0; I--) for (int J = Base / 10; J > 0; J /= 10) Out << V[I] / J % 10;
6 M# ], T8 ?8 \& A return Out;1 z' r2 X/ Q- k* c8 C
}: M( J) c+ p9 j0 E" s6 H
|