mirror of
https://gitlab.com/mfocko/Codeforces.git
synced 2024-11-09 13:49:06 +01:00
chore(cpp): factor out modular integer to a struct
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
35e432c481
commit
1bb9745299
1 changed files with 49 additions and 2 deletions
|
@ -151,14 +151,61 @@ Container collect(std::size_t size) {
|
||||||
#pragma endregion /* input */
|
#pragma endregion /* input */
|
||||||
|
|
||||||
#pragma region math
|
#pragma region math
|
||||||
static constexpr std::int32_t MODULO = 1000000007;
|
|
||||||
|
|
||||||
long pow(long base, long exp) {
|
long pow(long base, long exp) {
|
||||||
if (exp == 0) return 1;
|
if (exp == 0) return 1;
|
||||||
long half = pow(base, exp / 2);
|
long half = pow(base, exp / 2);
|
||||||
if (exp % 2 == 0) return half * half;
|
if (exp % 2 == 0) return half * half;
|
||||||
return half * half * base;
|
return half * half * base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <std::int64_t MODULO = 1000000007>
|
||||||
|
struct Z {
|
||||||
|
Z(std::int64_t x = 0) : x(x % MODULO) {}
|
||||||
|
|
||||||
|
Z pow(std::uint32_t exp) const {
|
||||||
|
auto ans = 1;
|
||||||
|
auto base = x;
|
||||||
|
|
||||||
|
for (; exp > 0; exp >>= 1) {
|
||||||
|
if (exp % 2 == 1) {
|
||||||
|
ans *= base;
|
||||||
|
}
|
||||||
|
|
||||||
|
base *= base;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
Z inv() const {
|
||||||
|
assert(x != 0);
|
||||||
|
return pow(MODULO - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
Z operator-() const { return {-x}; }
|
||||||
|
Z operator+=(const Z &rhs) { x = (x + rhs.x) % MODULO; }
|
||||||
|
Z operator-=(const Z &rhs) { x = (x - rhs.x) % MODULO; }
|
||||||
|
Z operator*=(const Z &rhs) { x = (x * rhs.x) % MODULO; }
|
||||||
|
Z operator/=(const Z &rhs) { x = (x * rhs.inv().x) % MODULO; }
|
||||||
|
|
||||||
|
friend Z operator+(Z lhs, const Z &rhs) { return lhs += rhs; }
|
||||||
|
friend Z operator-(Z lhs, const Z &rhs) { return lhs -= rhs; }
|
||||||
|
friend Z operator*(Z lhs, const Z &rhs) { return lhs *= rhs; }
|
||||||
|
friend Z operator/(Z lhs, const Z &rhs) { return lhs /= rhs; }
|
||||||
|
|
||||||
|
friend std::istream &operator>>(std::istream &is, Z &z) {
|
||||||
|
is >> z.x;
|
||||||
|
z.x %= MODULO;
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend std::ostream &operator<<(std::ostream &os, const Z &z) {
|
||||||
|
return os << z.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::int64_t x;
|
||||||
|
};
|
||||||
#pragma endregion /* math */
|
#pragma endregion /* math */
|
||||||
|
|
||||||
#pragma region output
|
#pragma region output
|
||||||
|
|
Loading…
Reference in a new issue