Skip to main content

ac_lib/math/
modint.rs

1#[derive(Clone)]
2pub struct ModInt {
3    value: i64,
4    modulus: i64,
5}
6
7impl ModInt {
8    pub fn new(value: i64, modulus: i64) -> Self {
9        let value = ((value % modulus) + modulus) % modulus;
10        ModInt { value, modulus }
11    }
12
13    pub fn add(&self, other: &ModInt) -> ModInt {
14        assert_eq!(self.modulus, other.modulus, "Moduli must be the same");
15        ModInt::new(self.value + other.value, self.modulus)
16    }
17
18    pub fn sub(&self, other: &ModInt) -> ModInt {
19        assert_eq!(self.modulus, other.modulus, "Moduli must be the same");
20        ModInt::new(self.value - other.value, self.modulus)
21    }
22
23    pub fn mul(&self, other: &ModInt) -> ModInt {
24        assert_eq!(self.modulus, other.modulus, "Moduli must be the same");
25        ModInt::new(self.value * other.value, self.modulus)
26    }
27
28    pub fn pow(&self, exponent: i64) -> ModInt {
29        let mut result = ModInt::new(1, self.modulus);
30        let mut base = self.clone();
31        let mut exp = exponent;
32
33        while exp > 0 {
34            if exp % 2 == 1 {
35                result = result.mul(&base);
36            }
37            base = base.mul(&base);
38            exp /= 2;
39        }
40
41        result
42    }
43
44    pub fn value(&self) -> i64 {
45        self.value
46    }
47}