-
Notifications
You must be signed in to change notification settings - Fork 191
/
Copy pathModInt.cpp
89 lines (79 loc) · 3.82 KB
/
ModInt.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/* Modulo int template */
/*
Inspired by [submission](https://codeforces.com/contest/1437/submission/96914548)
Verify: https://open.kattis.com/problems/modulararithmetic
*/
template<const int& MOD>
struct Mint {
using T = typename decay<decltype(MOD)>::type; T v;
Mint(int64_t v = 0) { if(v < 0) v = v % MOD + MOD; if(v >= MOD) v %= MOD; this->v = T(v); }
Mint(uint64_t v) { if (v >= MOD) v %= MOD; this->v = T(v); }
Mint(int v): Mint(int64_t(v)) {}
Mint(unsigned v): Mint(uint64_t(v)) {}
explicit operator int() const { return v; }
explicit operator int64_t() const { return v; }
explicit operator uint64_t() const { return v; }
friend istream& operator>>(istream& in, Mint& m) { int64_t v_; in >> v_; m = Mint(v_); return in; }
friend ostream& operator<<(ostream& os, const Mint& m) { return os << m.v; }
static T inv(T a, T m) {
T g = m, x = 0, y = 1;
while(a != 0) {
T q = g / a;
g %= a; swap(g, a);
x -= q * y; swap(x, y);
} return x < 0? x + m : x;
}
static unsigned fast_mod(uint64_t x, unsigned m = MOD) {
#if !defined(_WIN32) || defined(_WIN64)
return unsigned(x % m);
#endif // x must be less than 2^32 * m
unsigned x_high = unsigned(x >> 32), x_low = unsigned(x), quot, rem;
asm("divl %4\n" : "=a" (quot), "=d" (rem) : "d" (x_high), "a" (x_low), "r" (m));
return rem;
}
Mint inv() const { return Mint(inv(v, MOD)); }
Mint operator-() const { return Mint(v? MOD-v : 0); }
Mint& operator++() { v++; if(v == MOD) v = 0; return *this; }
Mint& operator--() { if(v == 0) v = MOD; v--; return *this; }
Mint operator++(int) { Mint a = *this; ++*this; return a; }
Mint operator--(int) { Mint a = *this; --*this; return a; }
Mint& operator+=(const Mint& o) { v += o.v; if (v >= MOD) v -= MOD; return *this; }
Mint& operator-=(const Mint& o) { v -= o.v; if (v < 0) v += MOD; return *this; }
Mint& operator*=(const Mint& o) { v = fast_mod(uint64_t(v) * o.v); return *this; }
Mint& operator/=(const Mint& o) { return *this *= o.inv(); }
friend Mint operator+(const Mint& a, const Mint& b) { return Mint(a) += b; }
friend Mint operator-(const Mint& a, const Mint& b) { return Mint(a) -= b; }
friend Mint operator*(const Mint& a, const Mint& b) { return Mint(a) *= b; }
friend Mint operator/(const Mint& a, const Mint& b) { return Mint(a) /= b; }
friend bool operator==(const Mint& a, const Mint& b) { return a.v == b.v; }
friend bool operator!=(const Mint& a, const Mint& b) { return a.v != b.v; }
friend bool operator<(const Mint& a, const Mint& b) { return a.v < b.v; }
friend bool operator>(const Mint& a, const Mint& b) { return a.v > b.v; }
friend bool operator<=(const Mint& a, const Mint& b) { return a.v <= b.v; }
friend bool operator>=(const Mint& a, const Mint& b) { return a.v >= b.v; }
Mint operator^(int64_t p) {
if(p < 0) return inv() ^ -p;
Mint a = *this, res{1}; while(p > 0) {
if(p & 1) res *= a;
p >>= 1; if(p > 0) a *= a;
} return res;
}
};
const int MOD = 1e9 + 7;
using mint = Mint<MOD>;
/*
mint a;
cin >> a;
cout << a;
>> mint a(2)
>> a.inv() // 500000004
>> a ^ -1 // 500000004
>> mint b = a * a + 2 * a - a / 32 // 437500011
>> b ^ 1234567890123456LL // 504998273
static int _MOD; // Mod values only known at run time may also be used by making the variable static
for(_MOD = 1; _MOD < 8; _MOD++) { // this way, the reference is known at compile time (requirement for non type template arguements)
Mint<_MOD> x(5); // yet the value may be modified during run time
cout << x << ' ';
}
Output: 0 1 2 1 0 5 5
*/