Skip to content

Commit c3e0515

Browse files
committed
feat: update modint
1 parent 4440303 commit c3e0515

22 files changed

Lines changed: 175 additions & 121 deletions
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#pragma once
2+
3+
/**
4+
* Author: Teetat T.
5+
* Date: 2026-04-15
6+
* Description: modular arithmetic operations
7+
*/
8+
9+
struct Barrett{
10+
u32 _m;
11+
u64 im;
12+
13+
explicit Barrett(u32 m):_m(m),im((u64)(-1)/m+1){}
14+
15+
u32 umod()const{return _m;}
16+
u32 mul(u32 a,u32 b)const{
17+
u64 z=a;
18+
z*=b;
19+
u64 x=(u64)(((unsigned __int128)(z)*im)>>64);
20+
u64 y=x*_m;
21+
return (u32)(z-y+(z<y?_m:0));
22+
}
23+
};
24+
25+
template<int id>
26+
struct DynamicModInt{
27+
using mint = DynamicModInt;
28+
29+
u32 x;
30+
static Barrett bt;
31+
32+
constexpr DynamicModInt():x(0){}
33+
constexpr DynamicModInt(ll x):x((x%=get_mod())<0?x+get_mod():x){}
34+
explicit operator int()const{return (int)x;}
35+
constexpr static u32 umod(){return bt.umod();}
36+
constexpr static int get_mod(){return (int)bt.umod();}
37+
static void set_mod(u32 m){
38+
assert(m>=1);
39+
bt=Barrett(m);
40+
}
41+
42+
mint operator-()const{
43+
mint res;
44+
res.val=x?umod()-x:0;
45+
return res;
46+
}
47+
mint operator+()const{return *this;}
48+
49+
mint inv()const{
50+
int a=x,b=get_mod(),u=1,v=0,q=0;
51+
while(b>0){
52+
q=a/b;
53+
swap(a-=q*b,b);
54+
swap(u-=q*v,v);
55+
}
56+
return mint(u);
57+
}
58+
mint pow(ll n)const{
59+
mint res=1,a=*this;
60+
for(;n>0;a*=a,n>>=1)if(n&1)res*=a;
61+
return res;
62+
}
63+
mint &operator+=(const mint &o){
64+
if((x+=o.x)>=umod())x-=umod();
65+
return *this;
66+
}
67+
mint &operator-=(const mint &o){
68+
if((x-=o.x)>=umod())x+=umod();
69+
return *this;
70+
}
71+
mint &operator*=(const mint &o){
72+
x=bt.mul(x,o.x);
73+
return *this;
74+
}
75+
mint &operator/=(const mint &o){
76+
return *this*=o.inv();
77+
}
78+
79+
mint operator+(const mint &o)const{return mint(*this)+=o;}
80+
mint operator-(const mint &o)const{return mint(*this)-=o;}
81+
mint operator*(const mint &o)const{return mint(*this)*=o;}
82+
mint operator/(const mint &o)const{return mint(*this)/=o;}
83+
84+
mint &operator++(){return *this+=mint(1);}
85+
mint &operator--(){return *this-=mint(1);}
86+
mint operator++(int){mint res=*this;*this+=mint(1);return res;}
87+
mint operator--(int){mint res=*this;*this-=mint(1);return res;}
88+
89+
bool operator==(const mint &o)const{return x==o.x;}
90+
bool operator!=(const mint &o)const{return x!=o.x;}
91+
bool operator<(const mint &o)const{return x<o.x;}
92+
93+
friend istream &operator>>(istream &is,mint &o){ll x{};is>>x;o=mint(x);return is;}
94+
friend ostream &operator<<(ostream &os,const mint &o){return os<<o.x;}
95+
};
96+
template<int id>
97+
Barrett DynamicModInt<id>::bt=Barrett(998244353);
98+
using dmint = DynamicModInt<0>;

modular-arithmetic/modint.hpp

Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,77 @@
22

33
/**
44
* Author: Teetat T.
5-
* Date: 2024-03-17
5+
* Date: 2026-04-15
66
* Description: modular arithmetic operations
77
*/
88

9-
template<int M,int root=0>
9+
template<int mod,int root=0>
1010
struct ModInt{
1111
using mint = ModInt;
12+
13+
static_assert(mod>0,"mod must be positive");
14+
1215
int x;
16+
1317
constexpr ModInt():x(0){}
14-
constexpr ModInt(ll x):x(norm(x%get_mod())){}
15-
static int Mod;
16-
static constexpr int get_mod(){return M>0?M:Mod;}
17-
static constexpr void set_mod(int Mod_){Mod=Mod_;}
18-
static constexpr mint get_root(){return mint(root);}
19-
constexpr int norm(int x)const{if(x<0)x+=get_mod();if(x>=get_mod())x-=get_mod();return x;}
20-
explicit constexpr operator int()const{return x;}
21-
constexpr mint operator-()const{return mint()-mint(*this);};
22-
constexpr mint operator+()const{return mint(*this);};
23-
constexpr mint inv()const{
24-
int a=x,b=get_mod(),u=1,v=0,q=0;
18+
constexpr ModInt(ll x):x((x%=mod)<0?x+mod:x){}
19+
explicit operator int()const{return x;}
20+
constexpr static int get_mod(){return mod;}
21+
constexpr static mint get_root(){return mint(root);}
22+
23+
mint operator-()const{
24+
mint res;
25+
res.x=x?mod-x:0;
26+
return res;
27+
}
28+
mint operator+()const{return *this;}
29+
30+
mint inv()const{
31+
int a=x,b=mod,u=1,v=0,q=0;
2532
while(b>0){
2633
q=a/b;
27-
a-=q*b;
28-
u-=q*v;
29-
swap(a,b);
30-
swap(u,v);
34+
swap(a-=q*b,b);
35+
swap(u-=q*v,v);
3136
}
3237
return mint(u);
3338
}
34-
constexpr int mul(int a,int b)const{return 1LL*a*b%get_mod();}
35-
constexpr mint &operator+=(const mint &rhs){x=norm(x+rhs.x);return *this;}
36-
constexpr mint &operator-=(const mint &rhs){x=norm(x-rhs.x);return *this;}
37-
constexpr mint &operator*=(const mint &rhs){x=mul(x,rhs.x);return *this;}
38-
constexpr mint &operator/=(const mint &rhs){x=mul(x,rhs.inv().x);return *this;}
39-
constexpr mint &operator++(){return *this+=1;}
40-
constexpr mint &operator--(){return *this-=1;}
41-
constexpr mint operator++(int){mint res=*this;*this+=1;return res;}
42-
constexpr mint operator--(int){mint res=*this;*this-=1;return res;}
43-
friend constexpr mint operator+(mint lhs,const mint &rhs){return lhs+=rhs;}
44-
friend constexpr mint operator-(mint lhs,const mint &rhs){return lhs-=rhs;}
45-
friend constexpr mint operator*(mint lhs,const mint &rhs){return lhs*=rhs;}
46-
friend constexpr mint operator/(mint lhs,const mint &rhs){return lhs/=rhs;}
39+
mint pow(ll n)const{
40+
mint res=1,a=*this;
41+
for(;n>0;a*=a,n>>=1)if(n&1)res*=a;
42+
return res;
43+
}
44+
mint &operator+=(const mint &o){
45+
if((x+=o.x)>=mod)x-=mod;
46+
return *this;
47+
}
48+
mint &operator-=(const mint &o){
49+
if((x-=o.x)<0)x+=mod;
50+
return *this;
51+
}
52+
mint &operator*=(const mint &o){
53+
x=(ll(x)*o.x)%mod;
54+
return *this;
55+
}
56+
mint &operator/=(const mint &o){
57+
return *this*=o.inv();
58+
}
59+
60+
mint operator+(const mint &o)const{return mint(*this)+=o;}
61+
mint operator-(const mint &o)const{return mint(*this)-=o;}
62+
mint operator*(const mint &o)const{return mint(*this)*=o;}
63+
mint operator/(const mint &o)const{return mint(*this)/=o;}
64+
65+
mint &operator++(){return *this+=mint(1);}
66+
mint &operator--(){return *this-=mint(1);}
67+
mint operator++(int){mint res=*this;*this+=mint(1);return res;}
68+
mint operator--(int){mint res=*this;*this-=mint(1);return res;}
69+
70+
bool operator==(const mint &o)const{return x==o.x;}
71+
bool operator!=(const mint &o)const{return x!=o.x;}
72+
bool operator<(const mint &o)const{return x<o.x;}
73+
4774
friend istream &operator>>(istream &is,mint &o){ll x{};is>>x;o=mint(x);return is;}
4875
friend ostream &operator<<(ostream &os,const mint &o){return os<<o.x;}
49-
friend constexpr bool operator==(const mint &lhs,const mint &rhs){return lhs.x==rhs.x;}
50-
friend constexpr bool operator!=(const mint &lhs,const mint &rhs){return lhs.x!=rhs.x;}
51-
friend constexpr bool operator<(const mint &lhs,const mint &rhs){return lhs.x<rhs.x;} // for std::map
5276
};
53-
using mint32 = ModInt<0>;
54-
template<>
55-
int mint32::Mod=int(1e9)+7;
56-
77+
using mint998 = ModInt<998244353,3>;
78+
using mint107 = ModInt<1000000007>;

modular-arithmetic/modint64.hpp

Lines changed: 0 additions & 62 deletions
This file was deleted.

modular-arithmetic/montgomery-modint.hpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,4 @@ struct MontgomeryModInt{
108108
friend ostream &operator<<(ostream &os,const mint &o){
109109
return os << o.val();
110110
}
111-
};
112-
using mint998 = MontgomeryModInt<998244353,3>;
113-
using mint107 = MontgomeryModInt<1000000007>;
114-
111+
};

polynomial/ntt.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#pragma once
22
#include "modular-arithmetic/binpow.hpp"
3-
#include "modular-arithmetic/montgomery-modint.hpp"
43

54
/**
65
* Author: Teetat T.

verify/yosupo/convolution/bitwise_and_convolution.test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#define PROBLEM "https://judge.yosupo.jp/problem/bitwise_and_convolution"
22
#include "template.hpp"
3-
#include "modular-arithmetic/montgomery-modint.hpp"
3+
#include "modular-arithmetic/modint.hpp"
44
#include "convolution/and-convolution.hpp"
55

66
using mint = mint998;

verify/yosupo/convolution/bitwise_or_convolution.test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#define PROBLEM "https://judge.yosupo.jp/problem/bitwise_and_convolution"
22
#include "template.hpp"
3-
#include "modular-arithmetic/montgomery-modint.hpp"
3+
#include "modular-arithmetic/modint.hpp"
44
#include "convolution/or-convolution.hpp"
55

66
using mint = mint998;

verify/yosupo/convolution/bitwise_xor_convolution.test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#define PROBLEM "https://judge.yosupo.jp/problem/bitwise_xor_convolution"
22
#include "template.hpp"
3-
#include "modular-arithmetic/montgomery-modint.hpp"
3+
#include "modular-arithmetic/modint.hpp"
44
#include "convolution/xor-convolution.hpp"
55

66
using mint = mint998;

verify/yosupo/convolution/convolution_mod.test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod"
22
#include "template.hpp"
3-
#include "modular-arithmetic/montgomery-modint.hpp"
3+
#include "modular-arithmetic/modint.hpp"
44
#include "polynomial/ntt.hpp"
55

66
using mint = mint998;

verify/yosupo/convolution/gcd_convolution.test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#define PROBLEM "https://judge.yosupo.jp/problem/gcd_convolution"
22
#include "template.hpp"
3-
#include "modular-arithmetic/montgomery-modint.hpp"
3+
#include "modular-arithmetic/modint.hpp"
44
#include "convolution/gcd-convolution.hpp"
55

66
using mint = mint998;

0 commit comments

Comments
 (0)