Skip to content

Commit a44275f

Browse files
Add modint and frac, comb; release 0.4.0
1 parent 84b0589 commit a44275f

File tree

7 files changed

+1957
-669
lines changed

7 files changed

+1957
-669
lines changed

library/mrpython/modint.hpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#ifndef MP_LIBRARY_MODINT_HPP
2+
#define MP_LIBRARY_MODINT_HPP
3+
#include <iostream>
4+
#include <mrpython/numeric.hpp>
5+
#include <type_traits>
6+
7+
namespace mrpython {
8+
template <unsigned P> class modint {
9+
static_assert(P > 0, "modint: P must be positive");
10+
static_assert(P < (1U << 31), "modint: P must be less than 2^31");
11+
12+
unsigned int v;
13+
14+
public:
15+
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
16+
constexpr modint(T x)
17+
: v((std::is_unsigned<T>::value
18+
? static_cast<unsigned int>(x % static_cast<T>(P))
19+
: static_cast<unsigned int>((x % static_cast<T>(P) + P) % P))) {}
20+
constexpr modint(void): v(0) {}
21+
constexpr modint& operator+=(modint x) {
22+
if ((this->v += x.v) >= P) this->v -= P;
23+
return *this;
24+
}
25+
constexpr modint& operator-=(modint x) {
26+
if (this->v < x.v) this->v += P;
27+
this->v -= x.v;
28+
return *this;
29+
}
30+
constexpr modint& operator*=(unsigned int x) {
31+
this->v = (unsigned long long int)this->v * x % P;
32+
return *this;
33+
}
34+
template <typename T,
35+
typename = std::enable_if_t<std::is_integral<T>::value &&
36+
!std::is_same<T, unsigned int>::value>>
37+
constexpr modint& operator*=(T x) {
38+
return *this *= modint(x);
39+
}
40+
constexpr modint& operator*=(modint x) {
41+
this->v = (unsigned long long int)this->v * x.v % P;
42+
return *this;
43+
}
44+
constexpr modint& operator/=(modint x) { return *this *= x.inv(); }
45+
constexpr friend modint operator+(modint a, modint b) {
46+
a += b;
47+
return a;
48+
}
49+
constexpr friend modint operator-(modint a, modint b) {
50+
a -= b;
51+
return a;
52+
}
53+
template <typename T,
54+
typename = std::enable_if_t<std::is_same<T, modint>::value ||
55+
std::is_integral<T>::value>>
56+
constexpr friend modint operator*(modint a, T b) {
57+
a *= b;
58+
return a;
59+
}
60+
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
61+
constexpr friend modint operator*(T a, modint b) {
62+
b *= a;
63+
return b;
64+
}
65+
constexpr friend modint operator/(modint a, modint b) { return a /= b; }
66+
constexpr modint operator-(void) const { return modint() - *this; }
67+
constexpr unsigned int val(void) const { return v; }
68+
constexpr friend std::ostream& operator<<(std::ostream& out, modint x) {
69+
return out << x.v;
70+
}
71+
constexpr modint inv(void) const { return mrpython::fastPow(*this, P - 2); }
72+
constexpr modint pow(unsigned long long int n) const {
73+
return mrpython::fastPow(*this, n);
74+
}
75+
static constexpr unsigned modval() { return P; }
76+
};
77+
} // namespace mrpython
78+
#endif // MP_LIBRARY_MODINT_HPP

library/mrpython/numeric.hpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#ifndef MP_LIBRARY_NUMERIC_HPP
2+
#define MP_LIBRARY_NUMERIC_HPP
3+
4+
#include <vector>
5+
namespace mrpython {
6+
template <typename T, typename F = std::multiplies<T>>
7+
constexpr T fastPow(T a, unsigned long long int n, T ans = 1,
8+
F const& f = F()) {
9+
while (n) {
10+
if (n & 1) ans = f(ans, a);
11+
a = f(a, a);
12+
n >>= 1;
13+
}
14+
return ans;
15+
}
16+
template <typename T> T frac(unsigned int n) {
17+
static std::vector<T> mem = {1};
18+
while (mem.size() <= n) mem.push_back(mem.back() * mem.size());
19+
return mem[n];
20+
}
21+
template <typename T> T comb(unsigned int n, unsigned int m) {
22+
return n < m ? 0 : frac<T>(n) / (frac<T>(m) * frac<T>(n - m));
23+
}
24+
} // namespace mrpython
25+
26+
#endif

library/mrpython/utility.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef MP_LIBRARY_UTILITY_HPP
22
#define MP_LIBRARY_UTILITY_HPP
33
#include <algorithm>
4-
#include <limits>
4+
#include <functional>
55

66
namespace mrpython {
77
struct max {

library/test/all.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
#include "lazy_segment_tree/all.hpp"
2+
#include "modint.cpp"
23
#include "sparse_table/all.hpp"
34
#include "typical_segment_tree/all.hpp"

0 commit comments

Comments
 (0)