1. 程式人生 > >51Nod-1029-大數除法

51Nod-1029-大數除法

ACM模版

描述

描述

題解

這種題除了用 java(程式碼 One) 外,我就只會套模版(程式碼 Two)了,寫起來賊累,當然,模版出奇跡!

程式碼

One:

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    private static Scanner cin;

    public static void main(String[] args) {
        cin = new Scanner(System.in);

        BigInteger A, B;
        A = cin.nextBigInteger();
        B = cin.nextBigInteger();

        System.out.println(A.divide(B));
        System.out.println(A.mod(B));
    }
}

Two:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstring>
#include <cmath>

typedef long long ll;

int powermod(int a, int exp, int moder)
{
    int ret = 1;
    for (; exp; exp >>= 1)
    {
        if (exp & 1
) { ret = 1ll * ret * a % moder; } a = 1ll * a * a % moder; } return ret; } void addminus(int *a, int *b, int &lengtha, int &lengthb, int type) { int length = std::max(lengtha, lengthb); for (int i = 0; i < length; ++i) { a[i] += type == 1
? b[i] : -b[i]; a[i] >= 10 ? (a[i] -= 10, ++a[i + 1]) : a[i] < 0 ? (a[i] += 10, --a[i + 1]) : 0; } for (lengtha = length + 1; lengtha && !a[lengtha - 1]; --lengtha) ; } struct BigInteger { const static int MAXN = 19; const static int MOD = (119 << 23) + 1; // 998244353 const static int root = 3; const static int invroot = 332748118; int a[1 << MAXN]; int length, sig; BigInteger() { memset(a, 0, sizeof(a)); length = sig = 0; } void clear() { memset(a, 0, sizeof(int) * length); length = sig = 0; } void read() { clear(); char ch = getchar(); for (; (ch < '0' || ch > '9') && ch != '-'; ch = getchar()) ; ch == '-' ? (sig = -1, ch = getchar()) : sig = 1; for (; ch >= '0' && ch <= '9'; ch = getchar()) { a[length ++] = ch - '0'; } std::reverse(a, a + length); for (; length && !a[length - 1]; --length) ; sig = length ? sig : 0; } void write() { if (!sig) { return (void)putchar('0'); } if (sig < 0) { putchar('-'); } for (int i = length - 1; i >= 0; i--) { putchar(a[i] + '0'); } } template <typename T> T tointeger() { T ret = 0; for (int i = length - 1; i >= 0; ++i) { ret = ret * 10 + a[i]; } return ret * sig; } bool equal(const BigInteger &p) const & { if (sig != p.sig || length != p.length) { return false; } for (int i = 0; i < length; ++i) { if (a[i] != p.a[i]) { return false; } } return true; } bool greater(const BigInteger &p) const & { if (sig != p.sig) { return sig > p.sig; } if (length != p.length) { return length > p.length ^ sig == -1; } for (int i = length - 1; i >= 0; --i) { if (a[i] > p.a[i]) { return sig > 0; } else if (a[i] < p.a[i]) { return sig < 0; } } return false; } void leftshift(int dis) { for (int i = length + dis - 1; i >= dis; --i) { a[i] = a[i - dis]; } memset(a, 0, sizeof(int) * dis); length += dis; } void rightshift(int dis) { if (dis >= length) { return clear(); } for (int i = 0; i < length - dis; ++i) { a[i] = a[i + dis]; } memset(a + length - dis, 0, sizeof(int) * dis); length = length - dis > 0 ? length - dis : 0; } void addone() { sig >= 0 ? ++ a[0] : --a[0]; for (int i = 0; i < length; ++i) { if (a[i] < 10 && a[i] >= 0) { break; } a[i] >= 10 ? (a[i] -= 10, ++a[i + 1]) : (a[i] += 10, --a[i + 1]); } if (a[length]) { ++length; } if (!a[length - 1]) { --length; } sig = length ? (sig >= 0 ? 1 : -1) : 0; } void minusone() { sig = -sig; addone(); sig = -sig; } bool absgreaterequal(BigInteger &q) { if (length != q.length) { return length > q.length; } for (int i = length - 1; i >= 0; -- i) { if (a[i] > q.a[i]) { return true; } if (a[i] < q.a[i]) { return false; } } return true; } void abs() { sig = std::abs(sig); } void neg() { sig = -sig; } void assign(BigInteger &q) { memset(a, 0, sizeof(int) * length); memcpy(a, q.a, sizeof(int) * q.length); length = q.length; sig = q.sig; } template <typename T> void assign(T q) { memset(a, 0, sizeof(int) * length); if (!q) { return (void)(sig = length = 0); } q < 0 ? sig = -1, q = -q : sig = 1; length = 0; for (; q; q /= 10) { a[length++] = q % 10; } } void add(BigInteger &q) { static BigInteger aux; if (!q.sig) { return ; } if (!sig) { assign(q); return ; } if (sig == q.sig) { addminus(a, q.a, length, q.length, 1); return ; } if (absgreaterequal(q)) { addminus(a, q.a, length, q.length, -1); sig = length ? sig : 0; return ; } aux.assign(q); addminus(q.a, a, q.length, length, -1); assign(q); q.assign(aux); } void minus(BigInteger &q) { q.neg(); add(q); q.neg(); } void NTT(int *a, int length, int type) { int len = -1; for (int x = length; x; ++len, x >>= 1) ; for (int i = 1, j = 0; i < length - 1; ++i) { for (int s = length; j ^= s >>= 1, ~j & s; ) ; if (i < j) { std::swap(a[i], a[j]); } } for (int i = 1; i <= len; ++ i) { int unit = powermod(type == 1 ? root : invroot, (MOD - 1) >> i, MOD), szk = 1 << (i - 1); for (int j = 0; j < length; j += 1 << i) { for (int k = j, w = 1; k < j + szk; ++k) { int s = a[k], t = 1ll * w * a[k + szk] % MOD; a[k] = s + t >= MOD ? s + t - MOD : s + t; a[k + szk] = s - t < 0 ? s - t + MOD : s - t; w = 1ll * w * unit % MOD; } } } if (type == 1) { return ; } int inv = powermod(length, MOD - 2, MOD); for (int i = 0; i < length; ++ i) { a[i] = 1ll * a[i] * inv % MOD; } } void mult(BigInteger &q) { static int aux[1 << MAXN]; if (!sig || !q.sig) { return clear(); } int n = length + q.length; int lengthans = 1; for (; lengthans < n; lengthans <<= 1) ; memcpy(aux, q.a, sizeof(int) * lengthans); NTT(a, lengthans, 1); NTT(aux, lengthans, 1); for (int i = 0; i < lengthans; i++) { a[i] = 1ll * a[i] * aux[i] % MOD; } NTT(a, lengthans, -1); for (int i = 0; i < n - 1; i++) { a[i + 1] += a[i] / 10; a[i] %= 10; } length = n; for (; length && !a[length - 1]; --length) ; sig *= q.sig; } void mult(int q) { if (!q || !sig) { return clear(); } ll x = std::abs(q), remain = 0; for (int i = 0; i < length; ++i) { remain += a[i] * x; a[i] = remain % 10; remain /= 10; } a[length] = (int)remain; for (; a[length]; ++length) { a[length + 1] = a[length] / 10; a[length] %= 10; } for (; length && !a[length - 1]; --length) ; sig *= q < 0 ? -1 : 1; } void power(int exp) { static BigInteger aux; if (!sig) { return ; } aux.assign<int> (1); for (; exp; exp >>= 1) { if (exp & 1) { aux.mult(*this); } aux.mult(aux); } assign(aux); } void divide(BigInteger &q) { static BigInteger aux, aux1; if (!sig || !q.sig) { return ; } if (length < q.length) { return clear(); } bool neg1 = sig == 1, neg2 = q.sig == 1; abs(), q.abs(); int num = 0; for (int i = q.length - 1; i >= q.length - 3; --i) { (num *= 10) += i >= 0 ? q.a[i] : 0; } num = 100000 / num; int nowprecision = 1; aux.assign<int> (num); for (; nowprecision <= length - q.length; nowprecision <<= 1) { aux1.clear(); aux1.length = (nowprecision << 1) + 3, aux1.sig = 1; for (int i = q.length - aux1.length; i < q.length; ++i) { aux1.a[i - q.length + aux1.length] = i >= 0 ? q.a[i] : 0; } aux1.mult(aux), aux1.rightshift(nowprecision + 2); aux1.mult(aux), aux1.rightshift(nowprecision + 2); aux.mult(2); aux.leftshift(nowprecision); aux.minus(aux1); } aux.mult(*this); aux.rightshift(q.length + nowprecision + 1); aux1.assign(aux); aux1.mult(q); minus(aux1); int flag = absgreaterequal(q) ? 2 : sig < 0 ? 1 : 0; assign(aux); if (flag) { flag == 1 ? minusone() : addone(); } if (!neg2) { q.neg(); } sig *= neg1 ^ neg2 ? -1 : 1; } int divide(int q) { if (!sig || !q) { return 0; } ll remain = 0, x = std::abs(q); for (int i = length - 1; i >= 0; --i) { remain = remain * 10 + a[i]; a[i] = (int)(remain / x); remain %= x; } for (; length && !a[length - 1]; --length) ; remain *= sig; sig *= q < 0 ? -1 : 1; if (!length) { sig = 0; } return (int)remain; } void sqrt() { static BigInteger aux, aux1, aux2; if (sig <= 0) { return ; } int num = 0; for (int i = length - 1; i >= length - 8; --i) { (num *= 10) += i >= 0 ? a[i] : 0; } ll x = length & 1 ? 10000000000000ll : 100000000000000ll; num = std::sqrt(1.0 * x / num); int nowprecision = 2; aux.assign<int> (num); for (; nowprecision <= (length >> 1) + 1; nowprecision = (nowprecision << 1) - 1) { aux1.clear(), aux2.clear(); aux1.length = (nowprecision << 1) + 1 + (length & 1), aux1.sig = 1; for (int i = length - aux1.length; i < length; ++i) { aux1.a[i - length + aux1.length] = i >= 0 ? a[i] : 0; } aux1.mult(aux), aux1.rightshift(nowprecision + 1); aux1.mult(aux), aux1.rightshift(nowprecision + 1); aux1.divide(2); aux2.length = (nowprecision + 1) << 1, aux2.sig = 1; aux2.a[aux2.length - 1] = 1, aux2.a[aux2.length - 2] = 5; aux2.minus(aux1); aux.mult(aux2); aux.rightshift(nowprecision + 2); } aux.mult(*this); aux.rightshift((length >> 1) + nowprecision + 1); aux1.assign(aux); aux1.mult(aux1); aux2.assign(*this); aux2.mult(2); minus(aux1); int flag = greater(aux2) ? 2 : sig < 0 ? 1 : 0; assign(aux); if (flag) { flag == 1 ? minusone() : addone(); } } }; BigInteger a, b, c; int main() { a.read(); b.read(); c.assign(a); a.divide(b); a.write(); putchar('\n'); a.mult(b); c.minus(a); c.write(); putchar('\n'); return 0; }