zoukankan      html  css  js  c++  java
  • INT128

    #include<bits/stdc++.h>
    #define DEBUG cerr << "Call out: " << __func__ << "	" << "Line: " << __LINE__ << "	 :"
    using namespace std;
    
    class INT128 {
    public:
    #define OPERATOR 9223372036854775808ull //(1 << 63)
    #define HERE (*this)
        unsigned long long HighPart, LowPart;
        INT128() { HighPart = 0; LowPart = 0; }
        INT128(long long p)
        {
            HighPart = 0; LowPart = 0; if (p >= 0) LowPart = p; else LowPart = p, HERE.rev();
        }
        INT128(long long p, long long q) { HighPart = p; LowPart = q; }
        void print() { cout << (bitset<64>)HighPart << ' ' << (bitset<64>)LowPart; }
        void printH() { cout << hex << HighPart << LowPart << dec << endl; }
        INT128 operator | (INT128 b) { return ((HighPart | b.HighPart), (LowPart | b.LowPart)); }
        INT128 operator & (INT128 b) { return ((HighPart & b.HighPart), (LowPart & b.LowPart)); }
        INT128 operator ^ (INT128 b) { return ((HighPart ^ b.HighPart), (LowPart ^ b.LowPart)); }
        bool operator < (INT128 b) { return (HERE - b).HighPart & OPERATOR; }
        bool operator <= (INT128 b) { return (HERE == b) | (HERE < b); }
        bool operator == (INT128 b) { return (HighPart == b.HighPart) && (LowPart == b.LowPart); }
    #define QAdd(a,b) 
        INT128(a.HighPart + b.HighPart + (a.LowPart >= 0-b.LowPart && (b.LowPart != 0)), a.LowPart + b.LowPart)
        inline INT128 rev() {
            INT128 p = HERE;
            p.HighPart = ~p.HighPart; p.LowPart = ~p.LowPart;
            return QAdd(p, (INT128(1)));
        }
        INT128 operator << (int st) {
            if (st == 0) return HERE;
            if (st >= 64) return INT128(LowPart << (st - 64), 0);
            else return INT128((HighPart << st | LowPart >> (64 - st)), LowPart << st);
        }
        INT128 operator >> (int st) {
            if (st == 0) return HERE;
            if (st >= 64) return INT128(0, HighPart >> (st - 64));
            else return INT128(HighPart >> st, (LowPart >> st | HighPart << (64 - st)));
        }
        bool operator [] (const int st) {
            return (st >= 64 ? ((HighPart >> (st - 64)) & 1) : ((LowPart >> (st)) & 1));
        }
        void change(int x, bool p) { // build successfully
            if (p) if (x >= 64) HighPart |= (1ll << (x - 64));
            else LowPart |= (1ll << (x));
            else if (x >= 64)
                if (((HighPart >> (x - 64)) & 1)) HighPart ^= (1ll << (x - 64)); else;
            else if (((LowPart >> (x)) & 1)) LowPart ^= (1ll << x);
        }
        INT128 operator / (long long st) { // build successfully
            INT128 nx = HERE;
            bool flag = (st & OPERATOR) ^ (HighPart & OPERATOR);
            if (st & OPERATOR) st = -st;
            if (HighPart & OPERATOR) nx = -nx;
            INT128 tmp = st; assert(st != 0);
            int len = log2(st) + 1; INT128 ret = 0;
            for (int i = 127 - len; i >= 0; i--) {
                if ((tmp << i) <= nx) ret.change(i, 1), nx = nx - (tmp << i);
            }
            if (flag) return -ret; else return ret;
        }
        long long operator % (long long st) {
            long long ret = 0;
            for (int i = 127; i >= 0; i--) {
                ret = ret * 2 + HERE[i];
                if (ret >= st) ret -= st;
            }
            return ret;
        }
        inline INT128 operator * (INT128 st) {
            register int flag;
            if ((HighPart & OPERATOR) ^ (st.HighPart & OPERATOR)) flag = 1;
            else flag = 0;
            register unsigned long long a1 = (unsigned int)LowPart, b1 = LowPart >> 32;
            register unsigned long long a2 = (unsigned int)st.LowPart, b2 = st.LowPart >> 32;
            INT128 ret = 
                (INT128)(a1 * a2) + // 0
                (((INT128)(a1 * b2) + (INT128)(a2 * b1)) << 32) + // 32
                (((INT128)(a1 * (unsigned int)st.HighPart + b1 * b2 + (unsigned int)HighPart * a2)) << 64) + // 32 * 2
                (((INT128)(a1 * (st.HighPart >> 32) + b1 * (unsigned int)st.HighPart +
                           (unsigned int)HighPart * b2 + (HighPart >> 32) * a2)) << 96); // 32 * 3
            if (flag) return -ret;
            else return ret;
        }
        friend ostream& operator << (ostream& st, INT128 t) {
            static int a[51]; int top = 0;
            if (t < 0) putchar('-'), t = -t;
            while (t.HighPart || t.LowPart) {
                a[top++] = t % 10;
                t = t / 10;
            }
            while (top) putchar(a[--top] + '0');
            return st;
        }
        INT128 operator + (INT128 p) { return QAdd(HERE, p); }
        INT128 operator - (INT128 p) { return QAdd(HERE, p.rev()); }
        INT128 operator - () { return HERE.rev(); }
        const INT128& operator=(const long long& p) { HERE = INT128(p); return HERE; }
        // operator long long(){ return LowPart; }
    //#undef OPERATOR
    #undef HERE
    }; // IF you just want to add, PLEASE use QAdd()
    INT128 time(INT128 a, INT128 st){
        register int flag;
        if ((a.HighPart & OPERATOR) ^ (st.HighPart & OPERATOR)) flag = 1;
        else flag = 0;
        register unsigned long long a1 = (unsigned int)a.LowPart, b1 = a.LowPart >> 32;
        register unsigned long long a2 = (unsigned int)st.LowPart, b2 = st.LowPart >> 32;
        INT128 ret = 
            (INT128)(a1 * a2) + // 0
            (((INT128)(a1 * b2) + (INT128)(a2 * b1)) << 32) + // 32
            (INT128)(((a1 * (unsigned int)st.HighPart + b1 * b2 + (unsigned int)a.HighPart * a2))  + // 32 * 2
            ((a1 * (st.HighPart >> 32) + b1 * (unsigned int)st.HighPart +
                       (unsigned int)a.HighPart * b2 + (a.HighPart >> 32) * a2)) << 32); // 32 * 3
        if (flag) return -ret;
        else return ret;
    }
    int main() {
        clock_t beg = clock();
        long long times = 0;
        INT128 a = 1000000ll, b = 10000000ll;
    //  a * a * b;
        const int tx = 1000;
        while (clock() - beg <= CLOCKS_PER_SEC) {
            for (int i = 1; i <= tx; i++)
                time(a,b);
            times += tx;
        }
        cout << "time:	" << times << endl;
        beg = clock();
        times = 0;
        while (clock() - beg <= CLOCKS_PER_SEC) {
            for (int i = 1; i <= tx; i++)
                QAdd(a,b);
            times += tx;
        }
        cout << "add:	" << times << endl;
    }
    
  • 相关阅读:
    codevs 1766 装果子
    codevs 1415 比那名居天子
    codevs 1388 砍树
    codevs 1373 射命丸文
    codevs 2867 天平系统3
    codevs 2866 天平系统2
    codevs 2865 天平系统1
    codevs 2832 6个朋友
    广搜优化题目总结
    Codeforces Round #578 (Div. 2)
  • 原文地址:https://www.cnblogs.com/dgklr/p/12254049.html
Copyright © 2011-2022 走看看