competitive_library/math/
mod_pow.rs

1//! 累乗剰余
2pub fn modpow(base: i64, exp: i64, n: i64) -> i64 {
3    let (mut base, mut exp, n) = (base as u128, exp, n as u128);
4
5    assert!(
6        exp >= 0,
7        "negative exponent cannot be used in modular exponentiation"
8    );
9
10    if exp == 0 {
11        return 1;
12    }
13
14    let mut res = 1;
15    base %= n;
16
17    loop {
18        if exp % 2 == 1 {
19            res *= &base;
20            res %= &n;
21        }
22
23        if exp == 1 {
24            return res as i64;
25        }
26
27        exp /= 2;
28        base *= base;
29        base %= n;
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use super::modpow;
36
37    #[test]
38    fn test_modpow() {
39        assert_eq!(modpow(3, 5, 5), 3);
40        assert_eq!(modpow(2, 32, 9), 4);
41    }
42}