首页 > 其他 > 详细

【数学】模运算类

时间:2021-06-01 23:56:41      阅读:44      评论:0      收藏:0      [点我收藏+]
/* MOD must be a prime. if not, don‘t use inv() */
const int MOD = 1e9 + 7;

struct ModularIntegers {
#define mint ModularIntegers
    int num;
    template <typename T>
    mint(const T& x) {
        ll tmp = x;
        if(tmp >= MOD) {
            if(tmp < (MOD << 1)) tmp -= MOD;
            else tmp %= MOD;
        } else if(tmp < 0) {
            if(tmp >= -MOD) tmp += MOD;
            else if(tmp %= MOD) tmp += MOD;
        }
        num = tmp;
    }
    friend mint operator+(const mint &x, const mint &y) {
        return x.num + y.num;
    }
    friend mint operator-(const mint &x, const mint &y) {
        return x.num - y.num;
    }
    friend mint operator*(const mint &x, const mint &y) {
        return x.num * y.num;
    }
    friend mint operator/(const mint &x, const mint &y) {
        return x * y.inv();
    }
    friend bool operator==(const mint &x, const mint &y) {
        return x.num == y.num;
    }
    friend bool operator!=(const mint &x, const mint &y) {
        return x.num != y.num;
    }
    mint& operator+=(const mint &x) {
        if((this->num += x.num) >= MOD) this->num -= MOD;
        return *this;
    }
    mint& operator-=(const mint & x) {
        if((this->num -= x.num) < 0) this->num += MOD;
        return *this;
    }
    mint& operator*=(const mint &x) {
        this->num = 1LL * this->num * x.num % MOD;
        return *this;
    }
    mint& operator/=(const mint & x) {
        this->num = ((*this) * x.inv()).num;
        return *this;
    }
    mint pow(ll x)const {
        mint res(1), cur(this->num);
        for(; x; cur *= cur, x >>= 1)
            if(x & 1) res *= cur;
        return res;
    }
    mint inv()const {
        return pow(MOD - 2);
    }
#undef mint
};

这个代码几乎是可以满足所有正常需求了,除了单个负号,自增自减这种很少用并且可以很方便替代的。

测试代码:

    for(int i = 1; i <= 200000; ++i) {
        mint a = 0;
        ll A = 0;

        ll rng = 1LL * rand() * rand();
        a -= rng;
        A -= rng;
        assert(a == (A % MOD + MOD) % MOD);
        WT(a, (A % MOD + MOD) % MOD);

        rng = 1LL * rand() * rand();
        a += rng;
        A += rng;
        WT(a, (A % MOD + MOD) % MOD);
        assert(a == (A % MOD + MOD) % MOD);

        rng = 1LL * rand() * rand();
        a *= rng;
        A *= rng;
        WT(a, (A % MOD + MOD) % MOD);
        assert(a == (A % MOD + MOD) % MOD);
    }

【数学】模运算类

原文:https://www.cnblogs.com/purinliang/p/14838826.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!