1
1
#pragma once
2
+ #include < cassert>
2
3
#include < iostream>
3
4
#include < set>
4
5
#include < vector>
5
6
6
7
template <int md> struct ModInt {
7
- #if __cplusplus >= 201402L
8
- #define MDCONST constexpr
9
- #else
10
- #define MDCONST
11
- #endif
12
8
using lint = long long ;
13
- MDCONST static int mod () { return md; }
9
+ constexpr static int mod () { return md; }
14
10
static int get_primitive_root () {
15
11
static int primitive_root = 0 ;
16
12
if (!primitive_root) {
@@ -36,52 +32,53 @@ template <int md> struct ModInt {
36
32
}
37
33
int val_;
38
34
int val () const noexcept { return val_; }
39
- MDCONST ModInt () : val_(0 ) {}
40
- MDCONST ModInt &_setval (lint v) { return val_ = (v >= md ? v - md : v), *this ; }
41
- MDCONST ModInt (lint v) { _setval (v % md + md); }
42
- MDCONST explicit operator bool () const { return val_ != 0 ; }
43
- MDCONST ModInt operator +(const ModInt &x) const {
35
+ constexpr ModInt () : val_(0 ) {}
36
+ constexpr ModInt &_setval (lint v) { return val_ = (v >= md ? v - md : v), *this ; }
37
+ constexpr ModInt (lint v) { _setval (v % md + md); }
38
+ constexpr explicit operator bool () const { return val_ != 0 ; }
39
+ constexpr ModInt operator +(const ModInt &x) const {
44
40
return ModInt ()._setval ((lint)val_ + x.val_ );
45
41
}
46
- MDCONST ModInt operator -(const ModInt &x) const {
42
+ constexpr ModInt operator -(const ModInt &x) const {
47
43
return ModInt ()._setval ((lint)val_ - x.val_ + md);
48
44
}
49
- MDCONST ModInt operator *(const ModInt &x) const {
45
+ constexpr ModInt operator *(const ModInt &x) const {
50
46
return ModInt ()._setval ((lint)val_ * x.val_ % md);
51
47
}
52
- MDCONST ModInt operator /(const ModInt &x) const {
48
+ constexpr ModInt operator /(const ModInt &x) const {
53
49
return ModInt ()._setval ((lint)val_ * x.inv ().val () % md);
54
50
}
55
- MDCONST ModInt operator -() const { return ModInt ()._setval (md - val_); }
56
- MDCONST ModInt &operator +=(const ModInt &x) { return *this = *this + x; }
57
- MDCONST ModInt &operator -=(const ModInt &x) { return *this = *this - x; }
58
- MDCONST ModInt &operator *=(const ModInt &x) { return *this = *this * x; }
59
- MDCONST ModInt &operator /=(const ModInt &x) { return *this = *this / x; }
60
- friend MDCONST ModInt operator +(lint a, const ModInt &x) {
51
+ constexpr ModInt operator -() const { return ModInt ()._setval (md - val_); }
52
+ constexpr ModInt &operator +=(const ModInt &x) { return *this = *this + x; }
53
+ constexpr ModInt &operator -=(const ModInt &x) { return *this = *this - x; }
54
+ constexpr ModInt &operator *=(const ModInt &x) { return *this = *this * x; }
55
+ constexpr ModInt &operator /=(const ModInt &x) { return *this = *this / x; }
56
+ friend constexpr ModInt operator +(lint a, const ModInt &x) {
61
57
return ModInt ()._setval (a % md + x.val_ );
62
58
}
63
- friend MDCONST ModInt operator -(lint a, const ModInt &x) {
59
+ friend constexpr ModInt operator -(lint a, const ModInt &x) {
64
60
return ModInt ()._setval (a % md - x.val_ + md);
65
61
}
66
- friend MDCONST ModInt operator *(lint a, const ModInt &x) {
62
+ friend constexpr ModInt operator *(lint a, const ModInt &x) {
67
63
return ModInt ()._setval (a % md * x.val_ % md);
68
64
}
69
- friend MDCONST ModInt operator /(lint a, const ModInt &x) {
65
+ friend constexpr ModInt operator /(lint a, const ModInt &x) {
70
66
return ModInt ()._setval (a % md * x.inv ().val () % md);
71
67
}
72
- MDCONST bool operator ==(const ModInt &x) const { return val_ == x.val_ ; }
73
- MDCONST bool operator !=(const ModInt &x) const { return val_ != x.val_ ; }
74
- MDCONST bool operator <(const ModInt &x) const {
68
+ constexpr bool operator ==(const ModInt &x) const { return val_ == x.val_ ; }
69
+ constexpr bool operator !=(const ModInt &x) const { return val_ != x.val_ ; }
70
+ constexpr bool operator <(const ModInt &x) const {
75
71
return val_ < x.val_ ;
76
72
} // To use std::map<ModInt, T>
77
73
friend std::istream &operator >>(std::istream &is, ModInt &x) {
78
74
lint t;
79
75
return is >> t, x = ModInt (t), is;
80
76
}
81
- MDCONST friend std::ostream &operator <<(std::ostream &os, const ModInt &x) {
77
+ constexpr friend std::ostream &operator <<(std::ostream &os, const ModInt &x) {
82
78
return os << x.val_ ;
83
79
}
84
- MDCONST ModInt pow (lint n) const {
80
+
81
+ constexpr ModInt pow (lint n) const {
85
82
ModInt ans = 1 , tmp = *this ;
86
83
while (n) {
87
84
if (n & 1 ) ans *= tmp;
@@ -90,9 +87,11 @@ template <int md> struct ModInt {
90
87
return ans;
91
88
}
92
89
90
+ static constexpr int cache_limit = std::min(md, 1 << 21 );
93
91
static std::vector<ModInt> facs, facinvs, invs;
94
- MDCONST static void _precalculation (int N) {
95
- int l0 = facs.size ();
92
+
93
+ constexpr static void _precalculation (int N) {
94
+ const int l0 = facs.size ();
96
95
if (N > md) N = md;
97
96
if (N <= l0) return ;
98
97
facs.resize (N), facinvs.resize (N), invs.resize (N);
@@ -101,33 +100,74 @@ template <int md> struct ModInt {
101
100
for (int i = N - 2 ; i >= l0; i--) facinvs[i] = facinvs[i + 1 ] * (i + 1 );
102
101
for (int i = N - 1 ; i >= l0; i--) invs[i] = facinvs[i] * facs[i - 1 ];
103
102
}
104
- MDCONST ModInt inv () const {
105
- if (this ->val_ < std::min (md >> 1 , 1 << 21 )) {
103
+
104
+ constexpr ModInt inv () const {
105
+ if (this ->val_ < cache_limit) {
106
106
if (facs.empty ()) facs = {1 }, facinvs = {1 }, invs = {0 };
107
107
while (this ->val_ >= int (facs.size ())) _precalculation (facs.size () * 2 );
108
108
return invs[this ->val_ ];
109
109
} else {
110
110
return this ->pow (md - 2 );
111
111
}
112
112
}
113
- MDCONST ModInt fac () const {
113
+ constexpr ModInt fac () const {
114
114
while (this ->val_ >= int (facs.size ())) _precalculation (facs.size () * 2 );
115
115
return facs[this ->val_ ];
116
116
}
117
- MDCONST ModInt facinv () const {
117
+ constexpr ModInt facinv () const {
118
118
while (this ->val_ >= int (facs.size ())) _precalculation (facs.size () * 2 );
119
119
return facinvs[this ->val_ ];
120
120
}
121
- MDCONST ModInt doublefac () const {
121
+ constexpr ModInt doublefac () const {
122
122
lint k = (this ->val_ + 1 ) / 2 ;
123
123
return (this ->val_ & 1 ) ? ModInt (k * 2 ).fac () / (ModInt (2 ).pow (k) * ModInt (k).fac ())
124
124
: ModInt (k).fac () * ModInt (2 ).pow (k);
125
125
}
126
- MDCONST ModInt nCr (const ModInt &r) const {
127
- return (this ->val_ < r.val_ ) ? 0 : this ->fac () * (*this - r).facinv () * r.facinv ();
126
+
127
+ constexpr ModInt nCr (int r) const {
128
+ if (r < 0 or this ->val_ < r) return ModInt (0 );
129
+ return this ->fac () * (*this - r).facinv () * ModInt (r).facinv ();
130
+ }
131
+
132
+ constexpr ModInt nPr (int r) const {
133
+ if (r < 0 or this ->val_ < r) return ModInt (0 );
134
+ return this ->fac () * (*this - r).facinv ();
135
+ }
136
+
137
+ static ModInt binom (int n, int r) {
138
+ static long long bruteforce_times = 0 ;
139
+
140
+ if (r < 0 or n < r) return ModInt (0 );
141
+ if (n <= bruteforce_times or n < (int )facs.size ()) return ModInt (n).nCr (r);
142
+
143
+ r = std::min (r, n - r);
144
+
145
+ ModInt ret = ModInt (r).facinv ();
146
+ for (int i = 0 ; i < r; ++i) ret *= n - i;
147
+ bruteforce_times += r;
148
+
149
+ return ret;
150
+ }
151
+
152
+ // Multinomial coefficient, (k_1 + k_2 + ... + k_m)! / (k_1! k_2! ... k_m!)
153
+ // Complexity: O(sum(ks))
154
+ template <class Vec > static ModInt multinomial (const Vec &ks) {
155
+ ModInt ret{1 };
156
+ int sum = 0 ;
157
+ for (int k : ks) {
158
+ assert (k >= 0 );
159
+ ret *= ModInt (k).facinv (), sum += k;
160
+ }
161
+ return ret * ModInt (sum).fac ();
128
162
}
129
- MDCONST ModInt nPr (const ModInt &r) const {
130
- return (this ->val_ < r.val_ ) ? 0 : this ->fac () * (*this - r).facinv ();
163
+
164
+ // Catalan number, C_n = binom(2n, n) / (n + 1)
165
+ // C_0 = 1, C_1 = 1, C_2 = 2, C_3 = 5, C_4 = 14, ...
166
+ // https://oeis.org/A000108
167
+ // Complexity: O(n)
168
+ static ModInt catalan (int n) {
169
+ if (n < 0 ) return ModInt (0 );
170
+ return ModInt (n * 2 ).fac () * ModInt (n + 1 ).facinv () * ModInt (n).facinv ();
131
171
}
132
172
133
173
ModInt sqrt () const {
0 commit comments