zoukankan      html  css  js  c++  java
  • 某科学的高精度板子

    #define LL long long
    #define MOD 1000000000
    #define BUFFER_SIZE 100000
     
    #define __base_t vector <int>
     
    namespace __BigInt_b
    {
    string convert_s(const __base_t &a)
    {
        static char buffer[BUFFER_SIZE]; char *ptr = buffer;
        ptr += sprintf(ptr, "%d", a[a.size() - 1]);
        for (int i = a.size() - 2; ~i; -- i)
            ptr += sprintf(ptr, "%09d", a[i]);
        string res(buffer);
        return res;
    }
     
    __base_t convert_b(const string &a)
    {
        __base_t c; c.resize((a.size() + 8) / 9);
        for (int i = a.size() - 1, j = 1; ~i; -- i, j = (j * 10 == MOD? 1: j * 10))
            c[(a.size() - i - 1) / 9] += (a[i] - '0') * j;
        return c;
    }
     
    LL convert_i(const __base_t &a)
    {
        LL b = 1, c = 0;
        for (int i = 0; i < a.size(); ++ i)
            c += a[i] * b, b = b * MOD;
        return c;
    }
     
    __base_t convert_b(LL a)
    {
        __base_t b;
        if (a == 0) b.push_back(0);
        while (a) b.push_back(a % MOD), a /= MOD;
        return b;
    }
     
    int __comp(const __base_t &a, const __base_t &b)
    {
        if (a.size() != b.size()) return a.size() < b.size()? -1: 1;
        for (int i = a.size() - 1; ~i; -- i)
            if (a[i] != b[i]) return a[i] < b[i]? -1: 1;
        return 0;
    }
     
    __base_t addi(const __base_t &a, const __base_t &b)
    {
        if (a.size() < b.size()) return addi(b, a);
        __base_t c = a; c.push_back(0);
        for (int i = 0; i < b.size() || c[i] >= MOD; ++ i)
        {
            if (i < b.size()) c[i] += b[i];
            if (c[i] >= MOD) c[i] -= MOD, c[i + 1] ++;
        }
        while (c.size() > 1 && !c[c.size() - 1]) c.pop_back();
        return c;
    }
     
    __base_t subt(const __base_t &a, const __base_t &b)
    {
        __base_t c = a;
        for (int i = 0; i < a.size() && (i < b.size() || c[i] < 0); ++ i)
        {
            if (i < b.size()) c[i] -= b[i];
            if (c[i] < 0)
                c[i] += MOD, c[i + 1] --;
        }
        while (c.size() > 1 && !c[c.size() - 1]) c.pop_back();
        return c;
    }
     
    __base_t mult(const __base_t &a, const __base_t &b)
    {
        __base_t c; c.resize(a.size() + b.size() + 1);
        LL k = 0;
        for (int i = 0; i < a.size(); ++ i)
        {
            for (int j = 0; j < b.size(); ++ j)
            {
                k = k + 1ll * a[i] * b[j] + c[i + j];
                c[i + j] = k % MOD;
                k /= MOD;
            }
            c[i + b.size()] = k;
            k = 0;
        }
        while (c.size() > 1 && !c[c.size() - 1]) c.pop_back();
        return c;
    }
     
    void trial_division(const __base_t &a, int b, __base_t &c, int &d)
    {
        c.resize(a.size());
        LL k = 0;
        for (int i = a.size() - 1; ~i; -- i)
        {
            k = k * MOD + a[i];
            c[i] = k / b;
            k %= b;
        }
        while (c.size() > 1 && !c[c.size() - 1]) c.pop_back();
        d = k;
    }
     
    __base_t divi(const __base_t &a, int b)
    {
        __base_t c; int d;
        trial_division(a, b, c, d);
        return c;
    }
     
    int modu(const __base_t &a, int b)
    {
        __base_t c; int d;
        trial_division(a, b, c, d);
        return d;
    }
     
    #define __trial_division_subt()
    {
        LL k = 0;
        for (int j = 0; j < b.size(); ++ j)
        {
            k = k - 1ll * p * b[j] + d[i + j];
            d[i + j] = k % MOD;
            k /= MOD;
            if (d[i + j] < 0) d[i + j] += MOD, k --;
        }
        if (k) d[i + b.size()] += k;
        c[i] += p;
    }
    #define __get_val(x, y, z) (10ull * MOD * ((y) + 1 < (z)? x[(y) + 1]: 0) + 10ull * x[(y)] + ((y) - 1 >= 0? x[(y) - 1]: 0) / (MOD / 10))
    void trial_division(const __base_t &a, const __base_t &b, __base_t &c, __base_t &d)
    {
        if (a.size() < b.size())
        {
            c.resize(0);
            d = a;
            return;
        }
        c, d = a; c.clear(); c.resize(a.size() - b.size() + 1);
        for (int i = a.size() - b.size(); ~i; -- i)
        {
            int p;
            while (p = __get_val(d, i + (int)b.size() - 1, d.size()) / (__get_val(b, (int)b.size() - 1, b.size()) + 1), p)
                __trial_division_subt();
            p = 1;
            for (int j = b.size() - 1; ~j; -- j) if (d[j + i] != b[j])
            {
                p = b[j] < d[j + i];
                break;
            }
            if (p) __trial_division_subt();
        }
        while (c.size() > 1 && !c[c.size() - 1]) c.pop_back();
        while (d.size() > 1 && !d[d.size() - 1]) d.pop_back();
    }
     
    __base_t divi(const __base_t &a, const __base_t &b)
    {
        __base_t c, d;
        trial_division(a, b, c, d);
        return c;
    }
     
    __base_t modu(const __base_t &a, const __base_t &b)
    {
        __base_t c, d;
        trial_division(a, b, c, d);
        return d;
    }
    }
     
     
    struct BigInt
    {
        bool is_neg;
        __base_t data;
     
        BigInt() {}
        BigInt(LL x)
        {
            is_neg = x < 0; data = __BigInt_b::convert_b(abs(x));
        }
     
        BigInt(const string &x)
        {
            if (x[0] == '-') is_neg = 1, data = __BigInt_b::convert_b(x.substr(1, x.size() - 1));
            else is_neg = 0, data = __BigInt_b::convert_b(x);
        }
     
        string to_string() const
        {
            if (data.size() == 1 && data[0] == 0) return "0";
            else return (is_neg? "-": "") + __BigInt_b::convert_s(data);
        }
     
        LL to_int() const
        {
            return (is_neg? -1: 1) * __BigInt_b::convert_i(data);
        }
     
        BigInt operator + (const BigInt &b) const;
        BigInt operator - (const BigInt &b) const;
        template <typename T> BigInt & operator += (const T &b);
        template <typename T> BigInt & operator -= (const T &b);
        template <typename T> BigInt & operator *= (const T &b);
        template <typename T> BigInt & operator /= (const T &b);
        template <typename T> BigInt & operator %= (const T &b);
     
        BigInt & operator /= (int b);
     
    };
     
    ostream & operator << (ostream &out, const BigInt &x)
    {
        out << x.to_string(); return out;
    }
     
    istream & operator >> (istream &in, BigInt &x)
    {
        string t;
        in >> t;
        x = (BigInt)t;
        return in;
    }
     
    bool operator == (const BigInt &a, const BigInt &b) {if (a.is_neg != b.is_neg) return 0; return __BigInt_b::__comp(a.data, b.data) == 0;}
    bool operator != (const BigInt &a, const BigInt &b) {if (a.is_neg != b.is_neg) return 1; return __BigInt_b::__comp(a.data, b.data) != 0;}
    bool operator < (const BigInt &a, const BigInt &b) {if (a.is_neg != b.is_neg) return a.is_neg; return __BigInt_b::__comp(a.data, b.data) * (a.is_neg ? -1 : 1) < 0;}
    bool operator > (const BigInt &a, const BigInt &b) {if (a.is_neg != b.is_neg) return !a.is_neg; return __BigInt_b::__comp(a.data, b.data) * (a.is_neg ? -1 : 1) > 0;}
    bool operator <= (const BigInt &a, const BigInt &b) {if (a.is_neg != b.is_neg) return a.is_neg; return __BigInt_b::__comp(a.data, b.data) * (a.is_neg ? -1 : 1) <= 0;}
    bool operator >= (const BigInt &a, const BigInt &b) {if (a.is_neg != b.is_neg) return !a.is_neg; return __BigInt_b::__comp(a.data, b.data) * (a.is_neg ? -1 : 1) >= 0;}
     
    BigInt link(bool _is_neg, const __base_t &_data)
    {
        BigInt c; c.is_neg = _is_neg; c.data = _data; if (_data.size() == 1 && _data[0] == 0) c.is_neg = 0; return c;
    }
     
    BigInt BigInt::operator + (const BigInt &b) const
    {
        if (is_neg ^ b.is_neg)
        {
            if (__BigInt_b::__comp(data, b.data) >= 0) return link(is_neg, __BigInt_b::subt(data, b.data));
            else return link(b.is_neg, __BigInt_b::subt(b.data, data));
        }
        else return link(is_neg, __BigInt_b::addi(b.data, data));
    }
     
    BigInt BigInt::operator - (const BigInt &b) const
    {
        if (is_neg ^ b.is_neg) return link(is_neg, __BigInt_b::addi(b.data, data));
        else
        {
            if (__BigInt_b::__comp(data, b.data) >= 0) return link(is_neg, __BigInt_b::subt(data, b.data));
            else return link(!is_neg, __BigInt_b::subt(b.data, data));
        }
    }
     
    BigInt operator * (const BigInt &a, const BigInt &b) {return link(a.is_neg ^ b.is_neg, __BigInt_b::mult(a.data, b.data));}
    BigInt operator / (const BigInt &a, int b) {return link(a.is_neg ^ (b < 0? 1: 0), __BigInt_b::divi(a.data, abs(b)));}
    int operator % (const BigInt &a, int b) {return (a.is_neg? -1: 1) * __BigInt_b::modu(a.data, abs(b));}
    BigInt operator / (const BigInt &a, const BigInt &b) {return link(a.is_neg ^ b.is_neg, __BigInt_b::divi(a.data, b.data));}
    BigInt operator % (const BigInt &a, const BigInt &b) {return link(a.is_neg, __BigInt_b::modu(a.data, b.data));}
     
    #define __ext_opt(opt, __opt)
    template <typename T> BigInt operator opt (const T &a, const BigInt &b) { return (BigInt)(a) opt b;}
    template <typename T> BigInt operator opt (const BigInt &a, const T &b) { return a opt (BigInt)(b);}
    template <typename T> BigInt & BigInt::operator __opt (const T &b) {*this = *this opt (BigInt)b; return *this;}
     
    __ext_opt(+, +=)
    __ext_opt(-, -=)
    __ext_opt(*, *=)
    __ext_opt(/, /=)
    __ext_opt(%, %=)
     
    BigInt & BigInt::operator /= (int b) {*this = *this / b; return *this;}
     
    #undef LL
    #undef MOD
    #undef __base_t
    #undef __ext_opt
    View Code
  • 相关阅读:
    [51nod] 1088 最长回文子串 #Hash+二分
    [51nod] 1378 夹克老爷的愤怒 #树形DP
    [BZOJ] 2456: mode #众数计数法
    [51nod] 1199 Money out of Thin Air #线段树+DFS序
    [51nod] 1494 选举拉票 #算法设计策略
    [51nod] 1463 找朋友 #离线+扫描线
    [BZOJ] 2733: [HNOI2012]永无乡 #线段树合并+并查集
    [BZOJ] 1012: [JSOI2008]最大数maxnumber
    [Codeforces] E. Lomsat gelral #DSU on Tree
    [BZOJ] 4756: [Usaco2017 Jan]Promotion Counting #线段树合并+权值线段树
  • 原文地址:https://www.cnblogs.com/Yuhuger/p/9302239.html
Copyright © 2011-2022 走看看