Skip to content

Commit 7022cfc

Browse files
authored
feat(mint): Add mint compress structure #100
1 parent 4833781 commit 7022cfc

File tree

2 files changed

+106
-61
lines changed

2 files changed

+106
-61
lines changed

numeric/numeric_mint_compress.cpp

+42-61
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,44 @@
1-
template<typename T>
2-
T inverse(T a, T m) {
3-
a = (a + m) % m; if (a < static_cast<T>(a)) a += m;
4-
T b = m, u = 0, v = 1;
5-
while (static_cast<T>(a) > 0) {
6-
T t = b / a; b -= t * a; swap(a, b); u -= t * v; swap(u, v); }
7-
assert(b == static_cast<T>(1)); // zero division
8-
if (u < static_cast<T>(0)) u += m;
9-
if(b != static_cast<T>(1)) u = -1;
10-
return u;}
11-
12-
template<typename Type>
13-
struct Modular {
14-
using T = typename decay<decltype(Type::value)>::type;
15-
constexpr static T MD() { return Type::value; }
16-
T value;
17-
Modular() { value = static_cast<T>(0); }
18-
T normalize(int64_t num) {
19-
return static_cast<T>((-MD()<num&&num<MD()) ? num : num % MD()); }
20-
Modular(int64_t num) { value = normalize(num);
21-
if (value < static_cast<T>(0)) value += MD(); }
22-
friend bool operator==(const Modular& a, const Modular& b) {
23-
return a.value == b.value; }
24-
friend bool operator!=(const Modular& a, const Modular& b) {
25-
return !(a == b); }
26-
friend bool operator<(const Modular& a, const Modular& b) {
27-
return a.value < b.value; }
28-
friend ostream& operator<<(ostream& os, const Modular& number) {
29-
return os << static_cast<T>(number); }
30-
friend istream& operator>>(istream& stream, Modular& number) {
31-
T tmp; stream >> tmp; number = Modular(tmp);return stream; }
32-
friend string to_string(Modular a) { return to_string(a.value); }
33-
Modular& operator+=(const Modular& m) {
34-
if ((value += m.value) >= MD()) value -= MD(); return *this; }
35-
Modular& operator-=(const Modular& m) {
36-
if ((value -= m.value) < 0) value += MD(); return *this; }
37-
Modular& operator*=(const Modular& m) {
38-
value = static_cast<T>((1LL*value*m.value)%MD()); return *this; }
39-
Modular& operator/=(const Modular& m) { return (*this) *= inverse(m); }
40-
friend Modular inverse(const Modular& a) {
41-
assert(a.value != 0); return inverse(a.value, Type::value); }
42-
Modular operator-() const { return Modular(-value); }
43-
Modular& operator++() { return *this += 1; }
44-
Modular& operator--() { return *this -= 1; }
45-
friend Modular operator+(Modular a, const Modular& b) { return a += b; }
46-
friend Modular operator-(Modular a, const Modular& b) { return a -= b; }
47-
friend Modular operator*(Modular a, const Modular& b) { return a *= b; }
48-
friend Modular operator/(Modular a, const Modular& b) { return a /= b; }
49-
operator int() const { return static_cast<int>(value); }
50-
operator int64_t() const { return static_cast<int64_t>(value); }
1+
// Taken from mcqueencin (Oscar Sierra) library and modified
2+
template <int64_t MD> struct mint_t {
3+
int64_t m;
4+
mint_t(){};
5+
mint_t(const int64_t &o) : m(o){};
6+
mint_t operator*(const mint_t &o) const {
7+
return 1LL * ((m % MD) * (o.m % MD)) % MD;
8+
};
9+
mint_t operator+(const mint_t &o) const {
10+
return m + o.m < MD ? m + o.m : m + o.m - MD;
11+
}
12+
mint_t operator-(const mint_t &o) const {
13+
return m - o.m >= 0 ? m - o.m : m - o.m + MD;
14+
}
15+
mint_t operator^(int64_t e) const {
16+
if (e == 0)
17+
return 1;
18+
mint_t t = *this ^ (e / 2);
19+
if (e & 1)
20+
return t * t * (*this);
21+
return t * t;
22+
}
23+
mint_t operator!() const { return *this ^ (MD - 2); }
24+
mint_t operator/(const mint_t &b) const { return *this * !b; };
25+
friend std::ostream &operator<<(std::ostream &os, const mint_t &a) {
26+
return os << a.m;
27+
}
28+
friend std::istream &operator>>(std::istream &is, mint_t &a) {
29+
int64_t val;
30+
is >> val;
31+
a = mint_t(val);
32+
return is;
33+
}
5134
};
52-
// using ModType = int__;
53-
// struct VarMod { static ModType value; };
54-
// ModType VarMod::value;
55-
// ModType& MOD = VarMod::value;
56-
// using Mint = Modular<VarMod>;
57-
const int MOD = int(1e9)+7;
58-
// Modular Integer -> Mint
59-
using Mint = Modular<integral_constant<decay<decltype(MOD)>::type, MOD>>;
6035

61-
bool is_zero_division(Mint &a) {
62-
using T = Mint::T; // don't forget to remove assert in reverse
63-
return inverse(static_cast<T>(a), MOD) < static_cast<T>(0); }
36+
const int64_t MD = 1e9 + 7;
37+
38+
using mint = mint_t<MD>;
39+
const mint ONE_mi = mint(1);
40+
const mint ZERO_mi = mint(0);
41+
42+
// usage:
43+
// mint X(...), N(...);
44+
// mint pw = X ^ N.m;

numeric/numeric_mint_medium.cpp

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
2+
template<typename T>
3+
T inverse(T a, T m) {
4+
a = (a + m) % m; if (a < static_cast<T>(a)) a += m;
5+
T b = m, u = 0, v = 1;
6+
while (static_cast<T>(a) > 0) {
7+
T t = b / a; b -= t * a; swap(a, b); u -= t * v; swap(u, v); }
8+
assert(b == static_cast<T>(1)); // zero division
9+
if (u < static_cast<T>(0)) u += m;
10+
if(b != static_cast<T>(1)) u = -1;
11+
return u;}
12+
13+
template<typename Type>
14+
struct Modular {
15+
using T = typename decay<decltype(Type::value)>::type;
16+
constexpr static T MD() { return Type::value; }
17+
T value;
18+
Modular() { value = static_cast<T>(0); }
19+
T normalize(int64_t num) {
20+
return static_cast<T>((-MD()<num&&num<MD()) ? num : num % MD()); }
21+
Modular(int64_t num) { value = normalize(num);
22+
if (value < static_cast<T>(0)) value += MD(); }
23+
friend bool operator==(const Modular& a, const Modular& b) {
24+
return a.value == b.value; }
25+
friend bool operator!=(const Modular& a, const Modular& b) {
26+
return !(a == b); }
27+
friend bool operator<(const Modular& a, const Modular& b) {
28+
return a.value < b.value; }
29+
friend ostream& operator<<(ostream& os, const Modular& number) {
30+
return os << static_cast<T>(number); }
31+
friend istream& operator>>(istream& stream, Modular& number) {
32+
T tmp; stream >> tmp; number = Modular(tmp);return stream; }
33+
friend string to_string(Modular a) { return to_string(a.value); }
34+
Modular& operator+=(const Modular& m) {
35+
if ((value += m.value) >= MD()) value -= MD(); return *this; }
36+
Modular& operator-=(const Modular& m) {
37+
if ((value -= m.value) < 0) value += MD(); return *this; }
38+
Modular& operator*=(const Modular& m) {
39+
value = static_cast<T>((1LL*value*m.value)%MD()); return *this; }
40+
Modular& operator/=(const Modular& m) { return (*this) *= inverse(m); }
41+
friend Modular inverse(const Modular& a) {
42+
assert(a.value != 0); return inverse(a.value, Type::value); }
43+
Modular operator-() const { return Modular(-value); }
44+
Modular& operator++() { return *this += 1; }
45+
Modular& operator--() { return *this -= 1; }
46+
friend Modular operator+(Modular a, const Modular& b) { return a += b; }
47+
friend Modular operator-(Modular a, const Modular& b) { return a -= b; }
48+
friend Modular operator*(Modular a, const Modular& b) { return a *= b; }
49+
friend Modular operator/(Modular a, const Modular& b) { return a /= b; }
50+
operator int() const { return static_cast<int>(value); }
51+
operator int64_t() const { return static_cast<int64_t>(value); }
52+
};
53+
// using ModType = int__;
54+
// struct VarMod { static ModType value; };
55+
// ModType VarMod::value;
56+
// ModType& MOD = VarMod::value;
57+
// using Mint = Modular<VarMod>;
58+
const int MOD = int(1e9)+7;
59+
// Modular Integer -> Mint
60+
using Mint = Modular<integral_constant<decay<decltype(MOD)>::type, MOD>>;
61+
62+
bool is_zero_division(Mint &a) {
63+
using T = Mint::T; // don't forget to remove assert in reverse
64+
return inverse(static_cast<T>(a), MOD) < static_cast<T>(0); }

0 commit comments

Comments
 (0)