|
高精度,用一个线性表保存一个大整数,具体说,将大整数写成p进制数,线性表的每一项存p进制其中一位。 参考下面代码 #include <iostream>3 u* E) b$ W l. o7 g
#include <memory>
9 Y+ z7 i* B, S) K6 J# include <string>2 p% v' ^! N0 ^$ S ]; F
using namespace std; typedef long long hugeint; const int Base = 1000000000;- t' G* P6 f# A8 Z4 A
const int Capacity = 200; struct xnum
# _ G6 f& H4 b+ Z* V{
9 c' V+ v: J- k% t7 U3 j int Len;
3 ~8 a& s5 e7 g int Data[Capacity];
1 t* I& K' H2 K xnum() : Len(0) {}
( `3 ~+ m" i- y/ J xnum(const xnum& V) : Len(V.Len) { memcpy(Data, V.Data, Len * sizeof *Data); }8 z1 q3 Z8 B+ Y* k5 t
xnum(int V) : Len(0) { for (; V > 0; V /= Base) Data[Len++] = V % Base; }) N- j N( M# h) v c7 ?
xnum& operator=(const xnum& V) { Len = V.Len; memcpy(Data, V.Data, Len * sizeof *Data); return *this; }/ h+ L" G% L$ S( U/ c
int& operator[](int Index) { return Data[Index]; }
' x7 s; j! q* N d8 w* Y: q int operator[](int Index) const { return Data[Index]; }
S1 O" R' Y8 w# V$ Z; U0 P6 v/ L4 K};
& x0 N7 J [3 Cint compare(const xnum& A, const xnum& B)
* l) @8 A O( M3 Q0 r0 E{
4 W1 L8 h/ T; S, j$ e" j int I;$ F. w4 P# v% _/ ^# y
if (A.Len != B.Len) return A.Len > B.Len ? 1 : -1;
; i2 Z5 @9 P" W7 d# x- b- `5 K) o for (I = A.Len - 1; I >= 0 && A[I] == B[I]; I--);6 p1 R4 H o" d7 [1 @/ T/ Q
if (I < 0) return 0;, M7 f0 Z; Q7 b3 l
return A[I] > B[I] ? 1 : -1;0 w5 ]- g* c! h) A. c) c8 M) G" V& V
} xnum operator+(const xnum& A, const xnum& B)) p) l+ @3 j9 x" D
{
% w! p! J% m; r- b9 g& n xnum R;; |, G1 b; D; W' Q/ x
int I;: j5 \# Q* i$ `4 u+ u
int Carry = 0;
J+ R! t6 ?7 S; _: X3 O for (I = 0; I < A.Len || I < B.Len || Carry > 0; I++)
1 M/ L! v( Z$ s: r5 S( C+ f# G# A {
1 m3 z: j& C* ?+ E. F6 e% M if (I < A.Len) Carry += A[I];
6 Z# K. R5 U6 l3 x/ L- m if (I < B.Len) Carry += B[I];" ?1 Q- m! w2 ^4 g
R[I] = Carry % Base;: N2 j- P- P* h+ ?1 m
Carry /= Base;( f0 v+ E& H$ x
}" R" L% i+ Z% }' @4 t0 B0 u+ U
R.Len = I;
( P3 U& H* P* Y$ C0 S return R;
9 u5 ~2 T U" m" g} xnum operator-(const xnum& A, const xnum& B)
! t) `$ R+ ]- [* _* t( ]6 w{
[& Y. U/ `+ T" T6 S4 Q xnum R;
& U" k$ g0 h2 t# F- t int Carry = 0;
1 }' r# ^$ ~ T1 Z# W U R.Len = A.Len;
' | l* K ~, v: ] int I;& k2 I% S$ P1 e3 L
for (I = 0; I < R.Len; I++)
_ _0 x9 e8 h1 g {# b6 R- f8 N- f% ]; c# X/ x
R[I] = A[I] - Carry;! p* r* x! d, i3 G: P, d9 k, J/ Z& J
if (I < B.Len) R[I] -= B[I];
( e6 X _, e3 ]& s if (R[I] < 0) Carry = 1, R[I] += Base;3 {4 L: ]; x1 U- o
else Carry = 0;
) a4 i% Z- U. _/ i3 O! l/ U4 I }
7 ~$ K, v/ [ b! O while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;
( i% t' }! S4 ^8 {0 A return R;
z0 b( J/ h/ c4 l; S7 ^' t} xnum operator*(const xnum& A, const int B)' c9 c! V6 t( F$ d' y# M; b1 I7 _/ R
{! S$ t0 f7 |+ Z
int I;
& t9 l3 Z% X, Y' O* A if (B == 0) return 0;; e% X+ q4 V+ g2 Q7 `" f5 u
xnum R;) A* y. x: V1 t5 P+ E/ F
hugeint Carry = 0;
; Q* y e p# ]$ e3 s for (I = 0; I < A.Len || Carry > 0; I++)" Q& \* I+ Q6 d/ r: y f1 F1 p
{
# B2 L9 D$ G1 T ^$ J: A if (I < A.Len) Carry += hugeint(A[I]) * B;
W; s, v7 i2 ~ R[I] = Carry % Base;# d# f/ ?% l# S
Carry /= Base;
9 C$ u6 A: k- ^, a. } }0 }' X, @0 B+ ~& ?! ~ `% C
R.Len = I;
7 E/ `+ L8 C: f return R;
! n9 @* h q) T4 i( H} xnum operator*(const xnum& A, const xnum& B)# q _* o1 o& z# K/ u+ }
{
1 O) \3 @. v3 p6 P: S) E8 h& W int I;# Q& o" ~+ _7 y
if (B.Len == 0) return 0;( [: O7 z/ A Z( K4 z
xnum R;( ]& e' s6 t7 g% c- @- U
for (I = 0; I < A.Len; I++)
2 i) g6 D* J* Y% ~3 {7 O {* U% U5 a" ?! r2 z5 t$ i. _/ c
hugeint Carry = 0;6 \0 Z1 m: [8 M+ Z8 s/ @$ X4 Q* Z( A9 @
for (int J = 0; J < B.Len || Carry > 0; J++)
1 C% _# C- o* V- v& ^3 e1 c {
! V/ G- r6 N0 W" u) c if (J < B.Len) Carry += hugeint(A[I]) * B[J];/ G# p6 L+ s- p2 Y- l: k
if (I + J < R.Len) Carry += R[I + J];
) X, j. _( v6 q' F0 S, V if (I + J >= R.Len) R[R.Len++] = Carry % Base;
& H- f0 A* @/ r# L& r* S; T else R[I + J] = Carry % Base;- ?* L! Y- |4 i" g9 F$ \# Z
Carry /= Base;
* c& q J! S8 H6 i% E }
6 Z4 i; I$ R3 u }
- P6 a7 z& O* ~ \* z& V- y) U return R;3 S/ q; R% k( B: B4 l- o) }
} xnum operator/(const xnum& A, const int B)
4 n) |- R6 c! {& e0 w K{
7 C* _4 K/ Q! \& X xnum R;% k \! b0 d8 a4 ^: p8 u. `/ n8 g& H9 s
int I;
3 }7 B5 `4 C0 T* P7 S3 a hugeint C = 0;- }( D; \5 v2 s8 m( }/ l3 l& j
for (I = A.Len - 1; I >= 0; I--)
! [4 A& J6 o9 }9 L+ o {
8 {1 s+ j4 U& L- r7 S$ i* G, s C = C * Base + A[I];9 ?: h# {* i# |' }
R[I] = C / B;
: f c- q% X: l C %= B;" @% z+ W2 D% s' s E
}$ |* G/ Z$ |9 l6 s- B
R.Len = A.Len;
2 q; a9 l; \: J& E6 A8 j6 ^ while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;
, x) X6 s* F. Q! }' g" i# d/ O return R;: G6 e$ b/ b9 g
} xnum operator/(const xnum& A, const xnum& B)( F9 S# U# |( ?
{8 h* h& s B: E- q2 h
int I;# z: U3 X% M+ V" ~& A% k% N
xnum R, Carry = 0;& p1 U$ ? W4 M5 j" i
int Left, Right, Mid;! D, \0 V9 u( @+ A' _$ K8 D3 S2 D+ m
for (I = A.Len - 1; I >= 0; I--); Q# `% h1 i s: u- N4 i3 C9 K- j. J+ E
{3 h' B, g9 A" z% E# C
Carry = Carry * Base + A[I];% a* I* [- ]6 M( V2 ~" ~$ T3 r
Left = 0;9 t( g, p6 r8 `9 O
Right = Base - 1;& ?; n; T- D5 t) O4 [, o
while (Left < Right)1 X$ h! R0 r8 ?: V5 o+ g
{
, y0 h; T* I0 k, M$ t6 V" f0 K Mid = (Left + Right + 1) / 2;
( L( x$ i, c( u8 G, p8 F, \& H if (compare(B * Mid, Carry) <= 0) Left = Mid;
/ `9 J- @( n. v' ^ else Right = Mid - 1;
) u1 S# b e* p2 M5 A3 K }
0 n. Z4 h8 J. k: [; K9 e V& d R[I] = Left;
) z& C, i; k1 d: \ H3 ^ Carry = Carry - B * Left;& ?7 b' B! s8 k% |- T+ j
}
2 e# ~/ c) o) X4 y5 C R.Len = A.Len;
$ { V2 {" l2 |' x$ j R. {& D/ p while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;
8 @: K) T$ h3 D: f2 T* c return R;
$ J% O; l- e" C* c}
" N. A, i0 W6 |! O8 h, y% r4 ^! {xnum operator%(const xnum& A, const xnum& B)
( ?$ n& ?8 {8 m{6 P* X6 X" I$ |( L5 j/ _' @- T! T
int I;) F. `9 i. s6 Y7 {2 G
xnum R, Carry = 0;! f; S, }' S4 S% Y5 I! ]3 s7 e6 u8 Z
int Left, Right, Mid;
: O# s G* y! g4 I, [ A for (I = A.Len - 1; I >= 0; I--)
" \/ Z) Z+ J0 d, d* i; B( l, K { j1 @$ p2 t3 c5 k5 G/ O. C- M; t
Carry = Carry * Base + A[I];7 o) ~. r4 d, O9 [% y
Left = 0;
" d8 o) M" Z( P/ J: d: U6 b Right = Base - 1;$ f* Q. Y1 }: k* W2 R# m2 v
while (Left < Right)+ {8 k- R* m& ]6 e* A6 ]
{
7 o" d6 `$ H6 \6 @2 H; l Mid = (Left + Right + 1) / 2;! C6 N. T# P2 b q! M+ d9 k X
if (compare(B * Mid, Carry) <= 0) Left = Mid;3 N* Q, B; k; z: E3 F, H
else Right = Mid - 1;
% O E# {7 R5 D1 `* w1 s }
8 U) n+ |* x1 N R[I] = Left;
" R/ H' b% S1 n7 {! k+ k Carry = Carry - B * Left;, \4 ]. b9 m6 a* W% R7 `+ H, m
}1 z) C! }9 ^5 R2 p H
R.Len = A.Len;! Z! n- h2 @# C5 q4 s/ L
while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;
# ]/ B7 p1 k) w8 N. J1 V. k return Carry;3 ?: l- B9 ]8 c- L& y5 I' o! r' o; o; o, ?
} istream& operator>>(istream& In, xnum& V)3 I3 Z7 z1 J) D) t& R
{
5 O3 z6 D" H/ J b char Ch;
0 }1 y# {6 [- W$ J6 a/ F for (V = 0; In >> Ch;)
; n$ e* M0 }4 n/ q" M1 J: B {
4 t# f$ W1 ^9 Z) w" s3 `6 `5 ~6 Z V = V * 10 + (Ch - '0');4 n1 j3 E4 O, c2 W# O
if (cin.peek() <= ' ') break;
$ ?& N2 D& u$ o& J }
7 e9 H- X) Y- L return In;6 x" o1 q* O9 Z6 q2 I$ E4 K2 m& M
} ostream& operator<<(ostream& Out, const xnum& V)
; d/ _+ H7 o9 A0 c" T5 u) F) x{
2 A3 v7 P6 h, L! k+ Q% F int I;
6 U) {3 }4 U' i- p$ V3 t- \' e Out << (V.Len == 0 ? 0 : V[V.Len - 1]);2 N e; Y8 P! {) f5 S, N- R
for (I = V.Len - 2; I >= 0; I--) for (int J = Base / 10; J > 0; J /= 10) Out << V[I] / J % 10;
$ \4 J: C$ o+ C. K" T return Out;
( p3 I9 z. x6 R5 m, ~}: v8 ]! n9 M* l2 V) l6 |7 \
|