|
高精度,用一个线性表保存一个大整数,具体说,将大整数写成p进制数,线性表的每一项存p进制其中一位。 参考下面代码 #include <iostream>
) {# L& _! k# J) p }# `2 m5 N" _#include <memory> n2 x( P% E9 }+ o+ L' D* e
# include <string>
* T3 L& x% E6 w( Q2 U, A* |using namespace std; typedef long long hugeint; const int Base = 1000000000;
. L5 |! p0 J& i6 K- D9 Bconst int Capacity = 200; struct xnum8 t3 c/ f6 b" x
{
0 h0 p. Z7 @2 D5 B int Len;
) y; f3 b" k4 J {% Z int Data[Capacity];: H7 Y+ l$ C, E! R- l1 v ?4 |! W e
xnum() : Len(0) {}
2 R7 @* S3 ^! G' d: a- V' x xnum(const xnum& V) : Len(V.Len) { memcpy(Data, V.Data, Len * sizeof *Data); }
. v% H0 \* p& N4 ~0 w xnum(int V) : Len(0) { for (; V > 0; V /= Base) Data[Len++] = V % Base; }
p+ W/ f# t7 Q1 X7 O; j; L2 y xnum& operator=(const xnum& V) { Len = V.Len; memcpy(Data, V.Data, Len * sizeof *Data); return *this; }
3 c6 u6 l& E$ D# p8 F/ t int& operator[](int Index) { return Data[Index]; }
7 F, G! x* q# z int operator[](int Index) const { return Data[Index]; }1 V6 f5 o$ M3 B! t, w+ R
}; ! {' }, ?. ?3 E# w4 g6 _9 g: V; M4 u
int compare(const xnum& A, const xnum& B)6 ~4 Z9 y! l0 {1 }! ^- s
{
$ M: p1 d V! _; p& Q$ V8 `( O4 F int I;
. N; l) d: E7 q+ Q& x" m& u/ j if (A.Len != B.Len) return A.Len > B.Len ? 1 : -1;# Q% ~2 ]+ _- I6 s6 n; B# f+ N4 x* R- v
for (I = A.Len - 1; I >= 0 && A[I] == B[I]; I--);: u, Q$ ?0 U) h* i" `( X- r- `
if (I < 0) return 0;
( ^, `# _! h- G. x8 J4 | return A[I] > B[I] ? 1 : -1; U7 p, z# c( `. B
} xnum operator+(const xnum& A, const xnum& B)& J, G+ e# z4 y& i# [2 s0 P
{
( ?/ K0 y2 _$ v) S xnum R;
8 v& X' @ @ R! ?8 i5 n int I;
) k& U" T- O! X, G8 } int Carry = 0;* `! Q: I. r8 x, n! q$ R: b" j" h
for (I = 0; I < A.Len || I < B.Len || Carry > 0; I++)
2 D4 N r; M( s2 K: O* |" e# G {
9 G7 {. f! X. [/ n% e if (I < A.Len) Carry += A[I];
8 v3 i1 u! U8 t! d. R7 G9 G4 h0 w if (I < B.Len) Carry += B[I];
/ P7 i- j" h0 j, x/ D0 Z- i& N R[I] = Carry % Base;1 ^5 P) p1 Z! I0 r1 w8 c
Carry /= Base;' c f0 h% \) X! q# j
}. a5 V, X% ? Y3 R: j$ d
R.Len = I;5 A+ D% @# ]/ D P
return R;
5 l" ?0 w4 T/ d! V+ `9 D0 V} xnum operator-(const xnum& A, const xnum& B)( e+ I/ s6 S3 N- |+ i
{4 _: M$ x( |' g( f7 E( i
xnum R;
# P, Y- _5 d+ X$ Z2 s. {6 l int Carry = 0;
+ l" i* o% N6 t" V/ u2 a m R.Len = A.Len;
8 V6 r. z# ]5 O0 i int I;
; b; i2 F! n7 N% }" l1 V for (I = 0; I < R.Len; I++); n" x+ }- k+ \+ `( J! v( j2 q
{" p0 s6 q0 x3 _0 f
R[I] = A[I] - Carry;
2 w7 f; m P3 t6 U t8 l if (I < B.Len) R[I] -= B[I];8 h) }3 t- h( }. C
if (R[I] < 0) Carry = 1, R[I] += Base;
+ Q6 C. R2 ]% I0 \ else Carry = 0;
8 X# D8 H( z6 G% { }, l% J" T8 m$ T$ M0 G( a# n" o. s
while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;
' U! }6 e& K6 [4 C' H! g return R;
5 i9 Z# a& F* @+ e; G} xnum operator*(const xnum& A, const int B)/ q1 P' g" K/ @. v
{
o& p% B! M- ^% { int I;
f: K* j( P; n2 P) h( i [ if (B == 0) return 0;
4 P; Y C; n2 |, h xnum R;+ d. N$ ~3 ]. p0 H2 I' f3 `- i
hugeint Carry = 0;
" L) A: ?) X8 V+ ^- y" k6 L7 t! E$ {1 I for (I = 0; I < A.Len || Carry > 0; I++)
. M* {$ V8 v. I6 Z2 V {4 [- W, ?$ ]$ \
if (I < A.Len) Carry += hugeint(A[I]) * B;
# X3 b) m9 A# r8 |4 h R[I] = Carry % Base;% q( M9 l D' T( ^2 |; p
Carry /= Base;/ R, U6 _( {6 V% }& D* F( ~' f2 X+ s
}3 G5 d8 T1 v: o4 @1 D- D
R.Len = I;5 u1 z. R% a0 z2 l' Z9 ]
return R;1 r3 I6 J5 t5 K; k/ F! Y7 c" ]+ {: T3 H
} xnum operator*(const xnum& A, const xnum& B)
& ^& c) z6 W; t) R* s& A{
% V" o8 s: q" M" L1 L; e. `. o int I;
+ b( s% @; r! {3 V" A7 J if (B.Len == 0) return 0;
- {8 B+ x) e0 \ xnum R;1 p# C/ A9 n+ Z. i
for (I = 0; I < A.Len; I++)( C- ?6 ~! V+ Z- }: ~+ N8 G
{
' S/ ~8 D: [" n6 h: h" ?2 l" A4 n! p hugeint Carry = 0;3 s) \$ F7 R: H- M: |2 R y
for (int J = 0; J < B.Len || Carry > 0; J++): ^4 f1 L% q ]; W4 P7 b
{9 o! G+ H% ~! y7 |" C/ O# D) R* G
if (J < B.Len) Carry += hugeint(A[I]) * B[J];+ ~7 A! o1 }6 G( Q
if (I + J < R.Len) Carry += R[I + J];
# I3 t( o( a, s- w& ^ if (I + J >= R.Len) R[R.Len++] = Carry % Base;
3 d8 Q# g; \( e7 C9 ]# w o3 b else R[I + J] = Carry % Base;
" i% X# x) }8 t/ D4 [ l Carry /= Base;' b& A! I7 O9 H5 H0 S
} - i4 v I2 ~2 L7 h; Z" ~
}
o# P4 m7 R0 A5 u: w3 p$ i$ B return R;; @0 X$ ^8 ^! K) k% F4 W
} xnum operator/(const xnum& A, const int B)
2 n6 B" ^( q# K8 q{
* s, J: P0 u! Z0 L9 f xnum R;
# x2 f9 j% p$ g; j( l int I;
; W$ M1 S5 o) T Z* Q hugeint C = 0;! K5 z6 b I; W2 O1 H6 \" H1 Y2 Y
for (I = A.Len - 1; I >= 0; I--)
" W/ v1 H0 a9 z {' }9 B5 M% F3 v, I# u1 C
C = C * Base + A[I];: |4 J% w: O$ d& |2 v8 `
R[I] = C / B;
( [. k; J' N9 m$ Q6 X: z! N3 Q C %= B;
- y1 ?+ k- r: W; I }
6 ^' N6 M' G" }6 g8 H* n5 S: B, ^ R.Len = A.Len;
. N) H: S8 z# B while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;0 _- c& y, t: p5 Z
return R;; Y! V8 k# m, M0 }. z; c0 T* _ W
} xnum operator/(const xnum& A, const xnum& B)8 h' B8 S* [* Y" _0 K% w
{: r$ H7 c; z [$ e( X
int I;) z: q. H6 Q* b4 j. ^ N* [) _
xnum R, Carry = 0;$ ^3 H7 x A! {* k% s$ P
int Left, Right, Mid;9 }; S) ~ l- a! r0 _8 o: U# t
for (I = A.Len - 1; I >= 0; I--)
0 _- R+ e7 } `2 }: `4 B( ? {( A9 W3 W* x' \* |
Carry = Carry * Base + A[I];
' g9 e/ y2 O# a u+ M2 C Left = 0;# T% R* ^0 e* K ^* o3 c# M0 x9 {
Right = Base - 1;* _+ ^% X3 J3 Y. D4 M. Z
while (Left < Right)
0 d9 V& ^3 J8 W* O) F. O { k9 r; R7 S, q. G$ M( E
Mid = (Left + Right + 1) / 2;; H& S8 o: s- b' O/ d# l
if (compare(B * Mid, Carry) <= 0) Left = Mid;
9 _. @. e, \8 u+ w else Right = Mid - 1;
, Q- c0 P% ^' H X }. U) E5 z% ?2 T z" A
R[I] = Left;6 Z) d& k, }8 Y; n3 N! u
Carry = Carry - B * Left;
/ ^4 p; ]( O& ~( t }" X9 W' D0 I" I( W# @6 O, J# w
R.Len = A.Len;
+ z" |9 K' y. ?2 j+ h( D! U while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;% H3 Z$ |% _7 ^# C5 w8 h" ^' {
return R;' H& t8 t. C: g x
}
: r% N7 K( x) T' h- X; lxnum operator%(const xnum& A, const xnum& B)8 H6 s6 j& N) _. M
{; K# ]! E1 `3 g+ R8 i4 K# E( P: S
int I;, _0 t# [4 y7 k# b$ w
xnum R, Carry = 0;
7 n! c* k; w+ C5 V) V int Left, Right, Mid;) S9 Q/ Z& l( k, n: T
for (I = A.Len - 1; I >= 0; I--)- \- |9 ~% Y l0 j& k7 b8 _, |. e
{
! A9 j/ v1 I+ ?# ~. H: j7 A- c Carry = Carry * Base + A[I];$ U8 e* ?4 _% O$ a; F
Left = 0;& c; O% f8 a5 S3 o
Right = Base - 1;
# [9 t8 d1 s% D# |6 W% o' ^* X while (Left < Right), t! c2 h# `# c) o7 ]5 H6 F
{
) H/ v" A b. k' X' ` Mid = (Left + Right + 1) / 2;! D* |8 u+ G x- U# f1 d+ f
if (compare(B * Mid, Carry) <= 0) Left = Mid;8 ]5 Y I# A2 m q
else Right = Mid - 1;
& T* p, i2 n! z }% t0 u0 i e6 G2 ^4 M
R[I] = Left; { J: s/ M Q1 v4 t3 F
Carry = Carry - B * Left; `0 n1 w: w4 U9 f
}4 n) F: P" |# }( B
R.Len = A.Len;& D% v: b, r( U7 r! r
while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;8 W5 T, o5 p- {# h# J9 J
return Carry;
! \ C/ c ~+ h! @# _: ^} istream& operator>>(istream& In, xnum& V)
" j1 }. u( Y3 O( j{
6 L1 \& D4 Q: H0 y3 f char Ch;- E4 A9 @6 T6 i5 h
for (V = 0; In >> Ch;)/ r( Q2 N$ M7 q- j* o3 g% M
{5 @/ D9 ~6 e" G* g# X
V = V * 10 + (Ch - '0');
. l% Q, K" h: v/ B$ q, f# }, o2 i$ | if (cin.peek() <= ' ') break;
$ o8 d o( P, H. n }
0 X/ Z+ c, L6 l+ B7 h return In;
% o9 |' u# C" P# z* d* E* q% y5 c} ostream& operator<<(ostream& Out, const xnum& V)
( V6 v8 j3 e5 l) L{
. p$ f3 ]/ A4 B0 j! n$ }! Q/ e int I;) F! j5 x( K& _; D* M( f
Out << (V.Len == 0 ? 0 : V[V.Len - 1]);
( j5 Z F! E6 B! D& a for (I = V.Len - 2; I >= 0; I--) for (int J = Base / 10; J > 0; J /= 10) Out << V[I] / J % 10;0 ?" |5 O. t7 i, y( \) L" D
return Out;
1 t& |: U, S2 y/ ~4 v}
' m N) o) x% k$ V8 g. R3 i, n |