competitive_library/math/
mod_pow.rs1pub 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}