maomao90's Library
A C++20 library for competitive programming.
Loading...
Searching...
No Matches
modint.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cassert>
4#include <concepts>
5#include <iostream>
6#include <type_traits>
7
13
14namespace maomao90 {
16struct modint_base {};
18} // namespace internal::modint
19using namespace std;
20template <typename T>
21concept ModInt = is_base_of_v<internal::modint::modint_base, T>;
22template <typename T>
23concept StaticModInt = is_base_of_v<internal::modint::static_modint_base, T>;
24
25template <auto mod = 998244353, enable_if_t<(mod >= 1), nullptr_t> = nullptr>
26 requires signed_integral<decltype(mod)> &&
27 internal::type_traits::is_64bit_or_less_v<decltype(mod)>
29private:
30 using M = decltype(mod);
31 using UM = make_unsigned_t<M>;
32 using BM = internal::type_traits::safely_multipliable_t<M>;
33
34public:
35 static constexpr bool is_prime_mod = is_prime((UM)mod);
36 using mod_type = M;
37 using umod_type = UM;
38 static constexpr M imod() { return mod; }
39 static constexpr UM umod() { return mod; }
40
41 static constexpr static_modint raw(M a) {
42 static_modint res;
43 res.v = a;
44 return res;
45 }
46
47 constexpr static_modint() : v(0) {}
48
49 template <internal::concepts::broadly_signed_integral T>
50 constexpr static_modint(T a) {
51 M x = a % imod();
52 if (x < 0) {
53 x += imod();
54 }
55 v = x;
56 }
57
58 template <internal::concepts::broadly_unsigned_integral T>
59 constexpr static_modint(T a) : v(a % umod()) {}
60
61 constexpr UM val() const { return v; }
62
63 constexpr static_modint operator+() const { return *this; }
64 constexpr static_modint operator-() const {
65 return raw(v == 0 ? 0 : imod() - v);
66 }
67
69 ++v;
70 if (v == umod()) {
71 v = 0;
72 }
73 return *this;
74 }
76 if (v == 0) {
77 v = umod();
78 }
79 --v;
80 return *this;
81 }
82 constexpr static_modint operator++(int) {
83 static_modint x = *this;
84 ++*this;
85 return x;
86 }
87 constexpr static_modint operator--(int) {
88 static_modint x = *this;
89 --*this;
90 return x;
91 }
92
93 constexpr static_modint &operator+=(const static_modint &o) {
94 v += o.v;
95 if (v >= umod()) {
96 v -= umod();
97 }
98 return *this;
99 }
101 if (v < o.v) {
102 v += umod();
103 }
104 v -= o.v;
105 return *this;
106 }
108 v = (BM)v * o.v % umod();
109 return *this;
110 }
112 return *this *= o.inv();
113 }
114
115 constexpr static_modint pow(long long p) const {
116 assert(p >= 0);
117 static_modint res = 1, b = *this;
118 while (p) {
119 if (p & 1) {
120 res *= b;
121 }
122 b *= b;
123 p >>= 1;
124 }
125 return res;
126 }
127 constexpr static_modint inv() const {
128 if constexpr (is_prime_mod) {
129 return pow(imod() - 2);
130 } else {
131 return raw(inv_gcd((M)v, imod()));
132 }
133 }
134
135 friend constexpr static_modint operator+(const static_modint &l,
136 const static_modint &r) {
137 static_modint res = l;
138 return res += r;
139 }
140 friend constexpr static_modint operator-(const static_modint &l,
141 const static_modint &r) {
142 static_modint res = l;
143 return res -= r;
144 }
145 friend constexpr static_modint operator*(const static_modint &l,
146 const static_modint &r) {
147 static_modint res = l;
148 return res *= r;
149 }
150 friend constexpr static_modint operator/(const static_modint &l,
151 const static_modint &r) {
152 static_modint res = l;
153 return res /= r;
154 }
155
156 constexpr bool operator==(const static_modint &o) const { return v == o.v; }
157 constexpr bool operator!=(const static_modint &o) const {
158 return !(*this == o);
159 }
160
161 friend constexpr istream &operator>>(istream &is, static_modint &o) {
162 M v;
163 is >> v;
164 o = static_modint(v);
165 return is;
166 }
167 friend constexpr ostream &operator<<(ostream &os, const static_modint &o) {
168 return os << o.v;
169 }
170
171private:
172 UM v;
173};
174
175template <int id = -1> struct dynamic_modint : internal::modint::modint_base {
176public:
177 static void set_mod(int mod) {
178 assert(1 <= mod);
179 bt = internal::math::barrett(mod);
180 }
181 static constexpr int imod() { return bt.umod(); }
182 static constexpr unsigned int umod() { return bt.umod(); }
183
184 static constexpr dynamic_modint raw(int a) {
185 dynamic_modint res;
186 res.v = a;
187 return res;
188 }
189
190 constexpr dynamic_modint() : v(0) {}
191
192 template <internal::concepts::broadly_signed_integral T>
193 constexpr dynamic_modint(T a) {
194 long long x = a % imod();
195 if (x < 0) {
196 x += imod();
197 }
198 v = x;
199 }
200
201 template <internal::concepts::broadly_unsigned_integral T>
202 constexpr dynamic_modint(T a) : v(a % umod()) {}
203
204 constexpr unsigned int val() const { return v; }
205 constexpr dynamic_modint operator+() const { return *this; }
206 constexpr dynamic_modint operator-() const {
207 return raw(v == 0 ? 0 : imod() - v);
208 }
209
211 ++v;
212 if (v == umod()) {
213 v = 0;
214 }
215 return *this;
216 }
218 if (v == 0) {
219 v = umod();
220 }
221 --v;
222 return *this;
223 }
224 constexpr dynamic_modint operator++(int) {
225 dynamic_modint x = *this;
226 ++*this;
227 return x;
228 }
229 constexpr dynamic_modint operator--(int) {
230 dynamic_modint x = *this;
231 --*this;
232 return x;
233 }
234
236 v += o.v;
237 if (v >= umod()) {
238 v -= umod();
239 }
240 return *this;
241 }
243 if (v < o.v) {
244 v += umod();
245 }
246 v -= o.v;
247 return *this;
248 }
250 v = bt.mul(v, o.v);
251 //_v = (long long)_v * o._v % umod();
252 return *this;
253 }
255 return *this *= o.inv();
256 }
257
258 constexpr dynamic_modint pow(long long p) const {
259 assert(p >= 0);
260 dynamic_modint res = 1, b = *this;
261 while (p) {
262 if (p & 1) {
263 res *= b;
264 }
265 b *= b;
266 p >>= 1;
267 }
268 return res;
269 }
270 constexpr dynamic_modint inv() const { return raw(inv_gcd((int)v, imod())); }
271
272 friend constexpr dynamic_modint operator+(const dynamic_modint &l,
273 const dynamic_modint &r) {
274 dynamic_modint res = l;
275 return res += r;
276 }
277 friend constexpr dynamic_modint operator-(const dynamic_modint &l,
278 const dynamic_modint &r) {
279 dynamic_modint res = l;
280 return res -= r;
281 }
282 friend constexpr dynamic_modint operator*(const dynamic_modint &l,
283 const dynamic_modint &r) {
284 dynamic_modint res = l;
285 return res *= r;
286 }
287 friend constexpr dynamic_modint operator/(const dynamic_modint &l,
288 const dynamic_modint &r) {
289 dynamic_modint res = l;
290 return res /= r;
291 }
292
293 constexpr bool operator==(const dynamic_modint &o) const { return v == o.v; }
294 constexpr bool operator!=(const dynamic_modint &o) const {
295 return !(*this == o);
296 }
297
298 friend constexpr istream &operator>>(istream &is, dynamic_modint &o) {
299 int v;
300 is >> v;
301 o = dynamic_modint(v);
302 return is;
303 }
304 friend constexpr ostream &operator<<(ostream &os, const dynamic_modint &o) {
305 return os << o.v;
306 }
307
308private:
309 unsigned int v;
311};
312template <int id> internal::math::barrett dynamic_modint<id>::bt(998244353);
313} // namespace maomao90
Definition modint.hpp:21
Definition modint.hpp:23
Definition modint.hpp:15
Definition hashmap.hpp:8
internal::math::barrett dynamic_modint< id >::bt(998244353)
constexpr T inv_gcd(T x, T mod)
Definition extended_gcd.hpp:12
constexpr bool is_prime(T n)
Definition primality_test.hpp:44
constexpr dynamic_modint & operator-=(const dynamic_modint &o)
Definition modint.hpp:242
constexpr dynamic_modint & operator*=(const dynamic_modint &o)
Definition modint.hpp:249
constexpr dynamic_modint & operator+=(const dynamic_modint &o)
Definition modint.hpp:235
constexpr bool operator==(const dynamic_modint &o) const
Definition modint.hpp:293
friend constexpr istream & operator>>(istream &is, dynamic_modint &o)
Definition modint.hpp:298
friend constexpr dynamic_modint operator-(const dynamic_modint &l, const dynamic_modint &r)
Definition modint.hpp:277
constexpr dynamic_modint inv() const
Definition modint.hpp:270
static void set_mod(int mod)
Definition modint.hpp:177
constexpr dynamic_modint & operator--()
Definition modint.hpp:217
constexpr unsigned int val() const
Definition modint.hpp:204
constexpr dynamic_modint operator--(int)
Definition modint.hpp:229
constexpr dynamic_modint pow(long long p) const
Definition modint.hpp:258
static constexpr unsigned int umod()
Definition modint.hpp:182
friend constexpr dynamic_modint operator+(const dynamic_modint &l, const dynamic_modint &r)
Definition modint.hpp:272
friend constexpr ostream & operator<<(ostream &os, const dynamic_modint &o)
Definition modint.hpp:304
constexpr dynamic_modint operator-() const
Definition modint.hpp:206
constexpr dynamic_modint()
Definition modint.hpp:190
constexpr dynamic_modint & operator/=(const dynamic_modint &o)
Definition modint.hpp:254
friend constexpr dynamic_modint operator/(const dynamic_modint &l, const dynamic_modint &r)
Definition modint.hpp:287
constexpr dynamic_modint operator++(int)
Definition modint.hpp:224
constexpr bool operator!=(const dynamic_modint &o) const
Definition modint.hpp:294
static constexpr dynamic_modint raw(int a)
Definition modint.hpp:184
constexpr dynamic_modint operator+() const
Definition modint.hpp:205
constexpr dynamic_modint(T a)
Definition modint.hpp:193
friend constexpr dynamic_modint operator*(const dynamic_modint &l, const dynamic_modint &r)
Definition modint.hpp:282
constexpr dynamic_modint & operator++()
Definition modint.hpp:210
static constexpr int imod()
Definition modint.hpp:181
Definition math.hpp:63
friend constexpr static_modint operator*(const static_modint &l, const static_modint &r)
Definition modint.hpp:145
M mod_type
Definition modint.hpp:36
constexpr static_modint & operator+=(const static_modint &o)
Definition modint.hpp:93
constexpr static_modint operator-() const
Definition modint.hpp:64
constexpr static_modint & operator--()
Definition modint.hpp:75
constexpr static_modint operator++(int)
Definition modint.hpp:82
constexpr static_modint operator--(int)
Definition modint.hpp:87
static constexpr M imod()
Definition modint.hpp:38
static constexpr bool is_prime_mod
Definition modint.hpp:35
constexpr static_modint & operator/=(const static_modint &o)
Definition modint.hpp:111
constexpr bool operator!=(const static_modint &o) const
Definition modint.hpp:157
constexpr static_modint & operator++()
Definition modint.hpp:68
constexpr static_modint inv() const
Definition modint.hpp:127
friend constexpr istream & operator>>(istream &is, static_modint &o)
Definition modint.hpp:161
constexpr UM val() const
Definition modint.hpp:61
friend constexpr static_modint operator-(const static_modint &l, const static_modint &r)
Definition modint.hpp:140
friend constexpr static_modint operator/(const static_modint &l, const static_modint &r)
Definition modint.hpp:150
friend constexpr ostream & operator<<(ostream &os, const static_modint &o)
Definition modint.hpp:167
UM umod_type
Definition modint.hpp:37
static constexpr UM umod()
Definition modint.hpp:39
constexpr static_modint(T a)
Definition modint.hpp:50
constexpr static_modint & operator-=(const static_modint &o)
Definition modint.hpp:100
constexpr static_modint pow(long long p) const
Definition modint.hpp:115
constexpr static_modint & operator*=(const static_modint &o)
Definition modint.hpp:107
static constexpr static_modint raw(M a)
Definition modint.hpp:41
constexpr static_modint()
Definition modint.hpp:47
constexpr static_modint operator+() const
Definition modint.hpp:63
constexpr bool operator==(const static_modint &o) const
Definition modint.hpp:156
friend constexpr static_modint operator+(const static_modint &l, const static_modint &r)
Definition modint.hpp:135