@@ -7,7 +7,6 @@ const assert = std.debug.assert;
77/// # Constraints
88///
99/// - `m >= 1` (otherwise a compile error)
10- ///
1110pub fn StaticModint (comptime m : comptime_int ) type {
1211 if (m < 1 ) {
1312 @compileError ("m must be greater than or equal to 1" );
@@ -108,7 +107,7 @@ pub fn StaticModint(comptime m: comptime_int) type {
108107 };
109108 }
110109
111- /// Returns `self / v (mod m)` (i.e. `self * inv(v)`).
110+ /// Returns `self / v (mod m)` (i.e., `self * inv(v)`).
112111 ///
113112 /// # Panics
114113 ///
@@ -181,40 +180,72 @@ pub fn StaticModint(comptime m: comptime_int) type {
181180 };
182181}
183182
183+ /// Modint for `mod = 998244353`.
184184pub const Modint998244353 = StaticModint (998244353 );
185+ /// Modint for `mod = 1000000007`.
185186pub const Modint1000000007 = StaticModint (1000000007 );
186187
188+ /// Modular integer with a **runtime**-set modulus.
189+ ///
190+ /// The modulus is shared across all values of the *same instantiation*
191+ /// `DynamicModint(id)`. Use different `id`s to keep separate global moduli.
187192pub fn DynamicModint (id : comptime_int ) type {
188193 return struct {
189194 const Self = @This ();
190- const _id = id ;
195+ const _id = id ; // disambiguates the type
191196
192- val : u32 ,
197+ /// Shared Barrett reducer for this type instantiation.
193198 var bt = internal .Barrett .init (998244353 );
194199
200+ /// Stored canonical representative in `[0, mod()-1]`.
201+ val : u32 ,
202+
203+ /// Returns the modulus.
195204 pub fn mod () u32 {
196205 return bt .umod ();
197206 }
198207
208+ /// Sets the modulus for this type.
209+ /// It must be called first.
210+ ///
211+ /// # Panics
212+ ///
213+ /// Panics if `m == 0`.
199214 pub fn setMod (m : u32 ) void {
200215 if (m == 0 ) {
201216 @panic ("the modulus must not be 0" );
202217 }
203218 Self .bt = internal .Barrett .init (m );
204219 }
205220
221+ /// Constructs `DynamicModint` from a `v < m` without taking mod.
222+ /// It is the function for constant-factor speedup.
223+ ///
224+ /// # Constraints
225+ ///
226+ /// - `v` is less than `m`
227+ ///
206228 pub fn raw (v : anytype ) Self {
207229 return Self {
208230 .val = @intCast (v ),
209231 };
210232 }
211233
234+ /// Returns the representative with casting to another integer `Type`.
235+ pub fn as (self : Self , Type : type ) Type {
236+ return @intCast (self .val );
237+ }
238+
239+ /// Constructs a value reduced modulo `m`.
240+ /// Works for both signed and unsigned integers.
212241 pub fn init (v : anytype ) Self {
213242 return Self {
214243 .val = takeMod (v ),
215244 };
216245 }
217246
247+ /// Monoid sum over a slice, reduced mod `m`.
248+ /// Returns `Σ v[i] (mod m)`.
218249 pub fn sum (Type : type , v : []const Type ) Self {
219250 var x = Self .init (0 );
220251 for (v ) | e | {
@@ -223,6 +254,8 @@ pub fn DynamicModint(id: comptime_int) type {
223254 return x ;
224255 }
225256
257+ /// Monoid product over a slice, reduced mod `m`.
258+ /// Returns `∏ v[i] (mod m)`.
226259 pub fn product (Type : type , v : []const Type ) Self {
227260 var x = Self .init (1 );
228261 for (v ) | e | {
@@ -231,6 +264,7 @@ pub fn DynamicModint(id: comptime_int) type {
231264 return x ;
232265 }
233266
267+ /// `self + v (mod mod())`.
234268 pub inline fn add (self : Self , v : anytype ) Self {
235269 const x = self .val + switch (@TypeOf (v )) {
236270 inline Self = > v .val ,
@@ -241,6 +275,7 @@ pub fn DynamicModint(id: comptime_int) type {
241275 };
242276 }
243277
278+ /// `self - v (mod mod())`.
244279 pub inline fn sub (self : Self , v : anytype ) Self {
245280 const x = self .val -% switch (@TypeOf (v )) {
246281 inline Self = > v .val ,
@@ -251,6 +286,7 @@ pub fn DynamicModint(id: comptime_int) type {
251286 };
252287 }
253288
289+ /// `self * v (mod mod())` using Barrett reduction.
254290 pub inline fn mul (self : Self , v : anytype ) Self {
255291 const x = bt .mul (self .val , switch (@TypeOf (v )) {
256292 inline Self = > v .val ,
@@ -261,6 +297,11 @@ pub fn DynamicModint(id: comptime_int) type {
261297 };
262298 }
263299
300+ /// `self / v (mod mod())` (i.e., `self * inv(v)`).
301+ ///
302+ /// # Panics
303+ ///
304+ /// Panics in debug if `v` is not invertible when `m` is composite.
264305 pub inline fn div (self : Self , v : anytype ) Self {
265306 const x = switch (@TypeOf (v )) {
266307 inline Self = > v .inv ().val ,
@@ -269,26 +310,32 @@ pub fn DynamicModint(id: comptime_int) type {
269310 return self .mul (x );
270311 }
271312
313+ /// In-place `+= v`.
272314 pub inline fn addAsg (self : * Self , v : anytype ) void {
273315 self .val = self .add (v ).val ;
274316 }
275317
318+ /// In-place `-= v`.
276319 pub inline fn subAsg (self : * Self , v : anytype ) void {
277320 self .val = self .sub (v ).val ;
278321 }
279322
323+ /// In-place `*= v`.
280324 pub inline fn mulAsg (self : * Self , v : anytype ) void {
281325 self .val = self .mul (v ).val ;
282326 }
283327
328+ /// In-place `/= v`.
284329 pub inline fn divAsg (self : * Self , v : anytype ) void {
285330 self .val = self .div (v ).val ;
286331 }
287332
333+ /// `-self (mod mod())`.
288334 pub inline fn negate (self : Self ) Self {
289335 return Self .raw (0 ).sub (self .val );
290336 }
291337
338+ /// Returns `self` to the power of `n`.
292339 pub inline fn pow (self : Self , n : anytype ) Self {
293340 assert (0 <= n );
294341 var x = self ;
@@ -303,6 +350,11 @@ pub fn DynamicModint(id: comptime_int) type {
303350 return r ;
304351 }
305352
353+ /// Retruns the multiplicative inverse of `self`.
354+ ///
355+ /// # Panics
356+ ///
357+ /// Panics if the multiplicative inverse does not exist.
306358 pub inline fn inv (self : Self ) Self {
307359 const g , const x = internal .invGcd (self .val , mod ());
308360 assert (g == 1 );
@@ -311,13 +363,16 @@ pub fn DynamicModint(id: comptime_int) type {
311363 };
312364 }
313365
366+ /// Reduce `v` modulo current `mod()` to a canonical `u32` in `[0, mod()-1]`.
314367 fn takeMod (v : anytype ) u32 {
315368 const m : i64 = @intCast (bt .umod ());
316369 return @intCast (@mod (v , m ));
317370 }
318371 };
319372}
320373
374+ /// Alias handy for dynamic-mod situations where the `id` value is irrelevant.
375+ /// You will usually want your own `id` to keep moduli separate across modules.
321376pub const Modint = DynamicModint (-1 );
322377
323378const testing = std .testing ;
0 commit comments