|
1 |
| -template<typename T> |
2 |
| -T inverse(T a, T m) { |
3 |
| - a = (a + m) % m; if (a < static_cast<T>(a)) a += m; |
4 |
| - T b = m, u = 0, v = 1; |
5 |
| - while (static_cast<T>(a) > 0) { |
6 |
| - T t = b / a; b -= t * a; swap(a, b); u -= t * v; swap(u, v); } |
7 |
| - assert(b == static_cast<T>(1)); // zero division |
8 |
| - if (u < static_cast<T>(0)) u += m; |
9 |
| - if(b != static_cast<T>(1)) u = -1; |
10 |
| - return u;} |
11 |
| - |
12 |
| -template<typename Type> |
13 |
| -struct Modular { |
14 |
| - using T = typename decay<decltype(Type::value)>::type; |
15 |
| - constexpr static T MD() { return Type::value; } |
16 |
| - T value; |
17 |
| - Modular() { value = static_cast<T>(0); } |
18 |
| - T normalize(int64_t num) { |
19 |
| - return static_cast<T>((-MD()<num&&num<MD()) ? num : num % MD()); } |
20 |
| - Modular(int64_t num) { value = normalize(num); |
21 |
| - if (value < static_cast<T>(0)) value += MD(); } |
22 |
| - friend bool operator==(const Modular& a, const Modular& b) { |
23 |
| - return a.value == b.value; } |
24 |
| - friend bool operator!=(const Modular& a, const Modular& b) { |
25 |
| - return !(a == b); } |
26 |
| - friend bool operator<(const Modular& a, const Modular& b) { |
27 |
| - return a.value < b.value; } |
28 |
| - friend ostream& operator<<(ostream& os, const Modular& number) { |
29 |
| - return os << static_cast<T>(number); } |
30 |
| - friend istream& operator>>(istream& stream, Modular& number) { |
31 |
| - T tmp; stream >> tmp; number = Modular(tmp);return stream; } |
32 |
| - friend string to_string(Modular a) { return to_string(a.value); } |
33 |
| - Modular& operator+=(const Modular& m) { |
34 |
| - if ((value += m.value) >= MD()) value -= MD(); return *this; } |
35 |
| - Modular& operator-=(const Modular& m) { |
36 |
| - if ((value -= m.value) < 0) value += MD(); return *this; } |
37 |
| - Modular& operator*=(const Modular& m) { |
38 |
| - value = static_cast<T>((1LL*value*m.value)%MD()); return *this; } |
39 |
| - Modular& operator/=(const Modular& m) { return (*this) *= inverse(m); } |
40 |
| - friend Modular inverse(const Modular& a) { |
41 |
| - assert(a.value != 0); return inverse(a.value, Type::value); } |
42 |
| - Modular operator-() const { return Modular(-value); } |
43 |
| - Modular& operator++() { return *this += 1; } |
44 |
| - Modular& operator--() { return *this -= 1; } |
45 |
| - friend Modular operator+(Modular a, const Modular& b) { return a += b; } |
46 |
| - friend Modular operator-(Modular a, const Modular& b) { return a -= b; } |
47 |
| - friend Modular operator*(Modular a, const Modular& b) { return a *= b; } |
48 |
| - friend Modular operator/(Modular a, const Modular& b) { return a /= b; } |
49 |
| - operator int() const { return static_cast<int>(value); } |
50 |
| - operator int64_t() const { return static_cast<int64_t>(value); } |
| 1 | +// Taken from mcqueencin (Oscar Sierra) library and modified |
| 2 | +template <int64_t MD> struct mint_t { |
| 3 | + int64_t m; |
| 4 | + mint_t(){}; |
| 5 | + mint_t(const int64_t &o) : m(o){}; |
| 6 | + mint_t operator*(const mint_t &o) const { |
| 7 | + return 1LL * ((m % MD) * (o.m % MD)) % MD; |
| 8 | + }; |
| 9 | + mint_t operator+(const mint_t &o) const { |
| 10 | + return m + o.m < MD ? m + o.m : m + o.m - MD; |
| 11 | + } |
| 12 | + mint_t operator-(const mint_t &o) const { |
| 13 | + return m - o.m >= 0 ? m - o.m : m - o.m + MD; |
| 14 | + } |
| 15 | + mint_t operator^(int64_t e) const { |
| 16 | + if (e == 0) |
| 17 | + return 1; |
| 18 | + mint_t t = *this ^ (e / 2); |
| 19 | + if (e & 1) |
| 20 | + return t * t * (*this); |
| 21 | + return t * t; |
| 22 | + } |
| 23 | + mint_t operator!() const { return *this ^ (MD - 2); } |
| 24 | + mint_t operator/(const mint_t &b) const { return *this * !b; }; |
| 25 | + friend std::ostream &operator<<(std::ostream &os, const mint_t &a) { |
| 26 | + return os << a.m; |
| 27 | + } |
| 28 | + friend std::istream &operator>>(std::istream &is, mint_t &a) { |
| 29 | + int64_t val; |
| 30 | + is >> val; |
| 31 | + a = mint_t(val); |
| 32 | + return is; |
| 33 | + } |
51 | 34 | };
|
52 |
| -// using ModType = int__; |
53 |
| -// struct VarMod { static ModType value; }; |
54 |
| -// ModType VarMod::value; |
55 |
| -// ModType& MOD = VarMod::value; |
56 |
| -// using Mint = Modular<VarMod>; |
57 |
| -const int MOD = int(1e9)+7; |
58 |
| -// Modular Integer -> Mint |
59 |
| -using Mint = Modular<integral_constant<decay<decltype(MOD)>::type, MOD>>; |
60 | 35 |
|
61 |
| -bool is_zero_division(Mint &a) { |
62 |
| - using T = Mint::T; // don't forget to remove assert in reverse |
63 |
| - return inverse(static_cast<T>(a), MOD) < static_cast<T>(0); } |
| 36 | +const int64_t MD = 1e9 + 7; |
| 37 | + |
| 38 | +using mint = mint_t<MD>; |
| 39 | +const mint ONE_mi = mint(1); |
| 40 | +const mint ZERO_mi = mint(0); |
| 41 | + |
| 42 | +// usage: |
| 43 | +// mint X(...), N(...); |
| 44 | +// mint pw = X ^ N.m; |
0 commit comments