高精板子
自己的板子用的比较放心(虽然在luogu TLE了一个点)
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; char s1[10010], s2[10010]; const int power = 4; const int base = 10000; struct Bignum { int a[10010]; Bignum() {memset(a, 0, sizeof a);} Bignum(char *s) { memset(a, 0, sizeof a); int len = strlen(s + 1); a[0] = (len + power - 1) / power; for(int i = 1, t = 0, w; i <= len; w *= 10, i++) { if( (i - 1) % power == 0) t++, w = 1; a[t] += w * (s[i] - '0'); } } inline void add(int x){if (x || a[0]) a[++a[0]] = x;} inline void rev(){reverse(a + 1, a + a[0] + 1);} inline void print() { printf("%d", a[a[0]]); for(int i = a[0] - 1; i >= 1; i--) printf("%0*d", power, a[i]); printf("\n"); } }p, q, ans; inline bool operator <(const Bignum &p, const Bignum &q) { if (p.a[0] < q.a[0]) return true; if (p.a[0] > q.a[0]) return false; for(int i = p.a[0]; i >= 1; i--) if (p.a[i] != q.a[i]) return p.a[i] < q.a[i]; return false; } inline bool operator ==(const Bignum &p, const Bignum &q) { if (p.a[0] != q.a[0]) return false; for(int i = 1; i <= p.a[0]; i++) if (p.a[i] != q.a[i]) return false; return true; } inline Bignum operator +(const Bignum &p, const Bignum &q) { Bignum pp; pp.a[0] = max(p.a[0], q.a[0]); for(int i = 1; i <= pp.a[0]; i++) { pp.a[i] += p.a[i] + q.a[i]; pp.a[i + 1] += pp.a[i] / base; pp.a[i] %= base; } if (pp.a[pp.a[0] + 1]) pp.a[0]++; return pp; } inline Bignum operator -(const Bignum &p, const Bignum &q) { Bignum pp = p; for(int i = 1; i <= pp.a[0]; i++) { pp.a[i] -= q.a[i]; if (pp.a[i] < 0) pp.a[i] += base, pp.a[i + 1] --; } while(pp.a[0] > 0 && !pp.a[pp.a[0]]) --pp.a[0]; return pp; } inline Bignum operator *(const Bignum &p, const Bignum &q) { Bignum pp; pp.a[0] = p.a[0] + q.a[0]; for(int i = 1; i <= p.a[0]; i++) for(int j = 1; j <= q.a[0]; j++) pp.a[i + j - 1] += p.a[i] * q.a[j], pp.a[i + j] += pp.a[i + j - 1] / base, pp.a[i + j - 1] %= base; if (!pp.a[pp.a[0]]) pp.a[0]--; return pp; } inline Bignum operator /(const Bignum &p, const Bignum &q) { Bignum x, y; x.a[0] = p.a[0]; for(int i = p.a[0]; i >= 1; i--) { y.add(p.a[i]); y.rev(); while(!(y < q)) y = y - q, x.a[i]++; y.rev(); } while(!x.a[x.a[0]]) x.a[0]--; return x; } inline Bignum operator %(const Bignum &p, const Bignum &q) { Bignum x = p / q; return p - x * q; } int main() { while(~scanf("%s%s", s1 + 1, s2 + 1)) { reverse(s1 + 1, s1 + strlen(s1 + 1) + 1); reverse(s2 + 1, s2 + strlen(s2 + 1) + 1); p = Bignum(s1); q = Bignum(s2); ans = p + q; ans.print(); if (p < q) printf("-"), ans = q - p, ans.print(); else ans = p - q, ans.print(); ans = p * q; ans.print(); ans = p / q; ans.print(); ans = p % q; ans.print(); } }
//高精*单精
inline Bignum operator*(const Bignum &p,ll q) { int i; Bignum ans=p; for(i=1;i<=ans.a[0];i++) ans.a[i]*=q; for(i=1;i<=ans.a[0];i++) { ans.a[i+1]+=ans.a[i]/Base; ans.a[i]%=Base; } while(ans.a[ans.a[0]+1]) { ans.a[0]++; ans.a[ans.a[0]+1]+=ans.a[ans.a[0]]/Base; ans.a[ans.a[0]]%=Base; } return ans; }
//高精/单精 inline Bignum operator/(const Bignum &p,ll q) { ll i,Sum=0; Bignum ans; ans.a[0]=p.a[0]; for(i=ans.a[0];i>=1;i--) { Sum=Sum*Base+p.a[i]; ans.a[i]=Sum/q; Sum%=q; } while(ans.a[0]&&(!ans.a[ans.a[0]])) ans.a[0]--; return ans; }
河田は河田、赤木は赤木……。
私は誰ですか。教えてください、私は誰ですか。
そうだ、俺はあきらめない男、三井寿だ!