/* 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