整數取模類

jxyanglinus發表於2024-11-05

實現一個整數取模類(加減乘除均可)。

template<int Mod, typename T = int> class ModInteger {
private:
	T x; // 數值本身,型別預設為 int
private:
	static T increase(const T &num) { return num >= Mod ? num - Mod : num; }
	static T decrease(const T &num) { return num < 0 ? num + Mod : num; }
public:
	ModInteger() : x(0) { }
	ModInteger(T num) : x(num >= 0 ? num % Mod : (Mod - (-num) % Mod) % Mod) { }
	ModInteger inverse() const {
		T a = x, u = 1, v = 0, k = 0; // 擴充套件歐幾里得求逆元
		int b = Mod;
		while (b > 0) {
			k = a / b;
			swap(a -= k * b, b);
			swap(u -= k * v, v);
		}
		return ModInteger(u);
	}
	static ModInteger pow(ModInteger a, ll b) {
		ModInteger res(1); // 快速冪,靜態成員函式,可直接在外部呼叫。
		while (b) {
			if (b & 1) res *= a;
			a *= a;
			b >>= 1;
		}
		return res;
	}
	ModInteger pow(ll b) const { return pow(*this, b); } // 快速冪,成員函式。
	ModInteger operator-() const { return ModInteger(-x); }
	ModInteger &operator+=(const ModInteger &rhs) { x = increase(x + rhs.x); return *this; }
	ModInteger &operator-=(const ModInteger &rhs) { x = decrease(x - rhs.x); return *this; }
	ModInteger &operator*=(const ModInteger &rhs) { x = 1ll * x * rhs.x % Mod; return *this; }
	ModInteger &operator/=(const ModInteger &rhs) { *this *= rhs.inverse(); return *this; } // 除以就相當於乘以逆元
	friend ModInteger operator+(const ModInteger &lhs, const ModInteger &rhs) { return ModInteger(lhs) += rhs; }
	friend ModInteger operator-(const ModInteger &lhs, const ModInteger &rhs) { return ModInteger(lhs) -= rhs; }
	friend ModInteger operator*(const ModInteger &lhs, const ModInteger &rhs) { return ModInteger(lhs) *= rhs; }
	friend ModInteger operator/(const ModInteger &lhs, const ModInteger &rhs) { return ModInteger(lhs) /= rhs; }
	
	bool operator==(const ModInteger &rhs) const { return x == rhs.x; }
	bool operator!=(const ModInteger &rhs) const { return x != rhs.x; }
	bool operator>=(const ModInteger &rhs) const { return x >= rhs.x; }
	bool operator<=(const ModInteger &rhs) const { return x <= rhs.x; }
	bool operator>(const ModInteger &rhs) const { return x > rhs.x; }
	bool operator<(const ModInteger &rhs) const { return x < rhs.x; }
	
    T data() const { return x; } // 獲取數值
    
	friend ostream &operator<<(ostream &os, const ModInteger &num) { return os << num.x; }
	friend istream &operator>>(istream &is, ModInteger &num) {
		T input;
		is >> input;
		num = ModInteger(input);
		return is;
	}
};

相關文章