cai_lw's competitive programming library
 
Loading...
Searching...
No Matches
mint2p61m1.hpp
1#pragma once
2
3#include <cstdint>
4#include <type_traits>
5
6#include "cplib/num/pow.hpp"
7
8namespace cplib {
9
18 public:
19 using mint = ModInt2P61M1;
20 using int_type = uint64_t;
21 using int_double_t = unsigned __int128;
22 static constexpr int_type MOD = (int_type(1) << 61) - 1;
23
24 constexpr ModInt2P61M1() : val_(0) {}
25
32 template <typename T, std::enable_if_t<std::is_integral_v<T> && std::is_signed_v<T>>* = nullptr>
33 explicit ModInt2P61M1(T x) {
34 auto r = x % std::make_signed_t<int_type>(MOD);
35 if (r < 0) {
36 r += MOD;
37 }
38 val_ = r;
39 }
40
42 template <typename T, std::enable_if_t<std::is_unsigned_v<T>>* = nullptr>
43 explicit ModInt2P61M1(T x) {
44 val_ = x % MOD;
45 }
46
48 int_type val() const { return val_; }
49
55 int_type residue() const { return val_; }
56
58 static constexpr int_type mod() { return MOD; }
59
60 mint& operator++() {
61 val_++;
62 if (val_ == MOD) {
63 val_ = 0;
64 }
65 return *this;
66 }
67
68 mint operator++(int) {
69 mint ret = *this;
70 ++(*this);
71 return ret;
72 }
73
74 mint operator+() const { return *this; }
75
76 mint operator+(const mint& rhs) const {
77 int_type r = val_ + rhs.val_;
78 return from_raw(r >= MOD ? r - MOD : r);
79 }
80
81 mint& operator+=(const mint& rhs) { return *this = *this + rhs; }
82
83 mint& operator--() {
84 if (val_ == 0) {
85 val_ = MOD - 1;
86 } else {
87 val_--;
88 }
89 return *this;
90 }
91
92 mint operator--(int) {
93 mint ret = *this;
94 --(*this);
95 return ret;
96 }
97
98 mint operator-() const { return from_raw(val_ == 0 ? 0 : MOD - val_); }
99
100 mint operator-(const mint& rhs) const {
101 int_type r = val_ + MOD - rhs.val_;
102 return from_raw(r >= MOD ? r - MOD : r);
103 }
104
105 mint& operator-=(const mint& rhs) { return *this = *this - rhs; }
106
107 mint operator*(const mint& rhs) const {
108 int_double_t prod = int_double_t(val_) * rhs.val_;
109 int_type r = (prod >> 61) + (prod & MOD);
110 return from_raw(r >= MOD ? r - MOD : r);
111 }
112
113 mint& operator*=(const mint& rhs) { return *this = *this * rhs; }
114
115 mint inv() const { return pow(*this, MOD - 2); }
116
117 mint operator/(const mint& rhs) const { return *this * rhs.inv(); }
118
119 mint& operator/=(const mint& rhs) { return *this *= rhs.inv(); }
120
121 bool operator==(const mint& rhs) const { return residue() == rhs.residue(); }
122
123 bool operator!=(const mint& rhs) const { return !(*this == rhs); }
124
125 private:
126 int_type val_;
127
128 static constexpr mint from_raw(int_type x) {
129 mint ret;
130 ret.val_ = x;
131 return ret;
132 }
133};
134
135} // namespace cplib
Modular integer modulo , a Mersenne prime.
Definition: mint2p61m1.hpp:17
int_type val() const
Converts back to a plain integer in the range .
Definition: mint2p61m1.hpp:48
int_type residue() const
Returns a number that is the same for the same residue class modulo the modulus.
Definition: mint2p61m1.hpp:55
static constexpr int_type mod()
Returns the modulus.
Definition: mint2p61m1.hpp:58
ModInt2P61M1(T x)
Converts a plain integer to a Barrett modular integer.
Definition: mint2p61m1.hpp:33
constexpr T pow(T base, uint64_t exp, Op &&op={})
A generic exponetiation by squaring function.
Definition: pow.hpp:14