@@ -25,16 +25,15 @@ namespace cp_algo::math {
2525 return modint::pw128 ();
2626 }
2727 static uint64_t m_reduce (__uint128_t ab) {
28- if (mod () % 2 == 0 ) {
28+ if (mod () % 2 == 0 ) [[unlikely]] {
2929 return ab % mod ();
3030 } else {
3131 uint64_t m = ab * imod ();
32- int64_t res = (ab + __uint128_t (m) * mod ()) >> 64 ;
33- return res < mod () ? res : res - mod ();
32+ return (ab + __uint128_t (m) * mod ()) >> 64 ;
3433 }
3534 }
3635 static uint64_t m_transform (uint64_t a) {
37- if (mod () % 2 == 0 ) {
36+ if (mod () % 2 == 0 ) [[unlikely]] {
3837 return a;
3938 } else {
4039 return m_reduce (a * pw128 ());
@@ -72,7 +71,25 @@ namespace cp_algo::math {
7271 modint operator - (const modint &t) const {return modint (to_modint ()) -= t;}
7372 modint operator * (const modint &t) const {return modint (to_modint ()) *= t;}
7473 modint operator / (const modint &t) const {return modint (to_modint ()) /= t;}
75- auto operator <=> (const modint_base &t) const = default ;
74+ // Why <=> doesn't work?..
75+ auto operator == (const modint_base &t) const {
76+ return std::min (r, r - mod ()) == std::min (t.r , t.r - mod ());
77+ }
78+ auto operator != (const modint_base &t) const {
79+ return std::min (r, r - mod ()) != std::min (t.r , t.r - mod ());
80+ }
81+ auto operator <= (const modint_base &t) const {
82+ return std::min (r, r - mod ()) <= std::min (t.r , t.r - mod ());
83+ }
84+ auto operator >= (const modint_base &t) const {
85+ return std::min (r, r - mod ()) >= std::min (t.r , t.r - mod ());
86+ }
87+ auto operator < (const modint_base &t) const {
88+ return std::min (r, r - mod ()) < std::min (t.r , t.r - mod ());
89+ }
90+ auto operator > (const modint_base &t) const {
91+ return std::min (r, r - mod ()) > std::min (t.r , t.r - mod ());
92+ }
7693 int64_t rem () const {
7794 uint64_t R = getr ();
7895 return 2 * R > (uint64_t )mod () ? R - mod () : R;
@@ -89,7 +106,10 @@ namespace cp_algo::math {
89106 return to_modint ();
90107 }
91108 void setr (uint64_t rr) {r = m_transform (rr);}
92- uint64_t getr () const {return m_reduce (r);}
109+ uint64_t getr () const {
110+ uint64_t res = m_reduce (r);
111+ return std::min (res, res - mod ());
112+ }
93113 void setr_direct (uint64_t rr) {r = rr;}
94114 uint64_t getr_direct () const {return r;}
95115 private:
0 commit comments