1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
use num::integer::{ExtendedGcd, Integer};
use num::traits::Signed;

pub fn mod_inv<A: Copy + Integer + Signed>(a: A, modulo: A) -> A {
    let ExtendedGcd { x, .. } = a.extended_gcd(&modulo);
    (modulo + x) % modulo
}

pub fn mod_pow(x: usize, n: usize, m: usize) -> usize {
    let mut res = 1;
    let mut x = x;
    let mut n = n;
    while n > 0 {
        if n & 1 == 1 {
            res = (res * x) % m;
        }
        x = (x * x) % m;
        n = n >> 1;
    }
    res
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_isize_mod_inv() -> () {
        const MOD: isize = 7;
        assert_eq!(1, mod_inv(1, MOD));
        assert_eq!(4, mod_inv(2, MOD));
        assert_eq!(5, mod_inv(3, MOD));
    }
}