跳转至

ModInt

模版
C++
template<class T> constexpr T qpow(T a, long long b) {
    T res = 1;
    while (b) {
        if (b & 1) res *= a;
        a *= a;
        b >>= 1;
    }
    return res;
}
template <class T> struct _MInt {
    T value;
    constexpr _MInt() : value() {}
    constexpr _MInt(T value) : value(normal(value % getMod())) {}
    static int _mod;
    constexpr static int getMod() {
        return _mod;
    }
    constexpr T normal(T x) const {
        if (x < 0) {
            x += getMod();
        }
        if (x >= getMod()) {
            x -= getMod();
        }
        return x;
    }
    constexpr _MInt inv() const {
        return qpow(*this, getMod() - 2);
    }
    constexpr _MInt operator-() const {
        _MInt res;
        res.value = normal(getMod() - value);
        return res;
    }
    constexpr _MInt &operator*=(_MInt rhs) & {
        if (is_same<T, long long>::value) {
            value = (__int128) value * rhs.x % getMod();
        } else {
            value = (long long) value * rhs.x % getMod();
        }
        return *this;
    }
    constexpr _MInt &operator+=(_MInt rhs) & {
        value = normal(value + rhs.value);
        return *this;
    }
    constexpr _MInt &operator-=(_MInt rhs) & {
        value = normal(value - rhs.value);
        return *this;
    }
    constexpr _MInt &operator/=(_MInt rhs) & {
        return *this *= rhs.inv(); 
    }
    friend constexpr _MInt operator*(_MInt lhs, _MInt rhs) {
        _MInt res = lhs;
        res *= rhs;
        return res;
    }
    friend constexpr _MInt operator+(_MInt lhs, _MInt rhs) {
        _MInt res = lhs;
        res += rhs;
        return res;
    }
    friend constexpr _MInt operator-(_MInt lhs, _MInt rhs) {
        _MInt res = lhs;
        res -= rhs;
        return res;
    }
    friend constexpr _MInt operator/(_MInt lhs, _MInt rhs) {
        _MInt res = lhs;
        res /= rhs;
        return res;
    }
    friend constexpr istream &operator>>(istream &is, _MInt &a) {
        long long v;
        is >> v;
        a = _MInt(v);
        return is;
    }
    friend constexpr ostream &operator<<(ostream &os, const _MInt &a) {
        return os << a.value;
    }
    friend constexpr bool operator==(_MInt lhs, _MInt rhs) {
        return lhs.value == rhs.value;
    }
    friend constexpr bool operator!=(_MInt lhs, _MInt rhs) {
        return lhs.value != rhs.value;
    }
};
template <> int _MInt<int>::_mod = 998244353;
using MInt = _MInt<int>;