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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
//! 冪乗。
/// 冪乗。
///
/// $a^b \\bmod n$ を返す。
///
/// # Complexity
/// $O(\\log(b))$ time.
///
/// # Examples
/// ```
/// use nekolib::math::ModPow;
///
/// assert_eq!(3_u64.mod_pow(14, 10), 9);
/// assert_eq!(2_u64.mod_pow(11, 1024), 0);
/// assert_eq!(0_u64.mod_pow(0, 1), 0);
/// ```
pub trait ModPow {
fn mod_pow(self, b: Self, n: Self) -> Self;
}
macro_rules! impl_uint {
($t:ty) => {
impl ModPow for $t {
fn mod_pow(self, mut b: Self, n: Self) -> Self {
if n == 1 {
return 0; // in case 0^0
}
let mut res = 1;
let mut a = self % n;
while b > 0 {
if b & 1 == 1 {
res = res * a % n;
}
a = a * a % n;
b >>= 1;
}
res
}
}
};
( $($t:ty)* ) => { $(impl_uint!($t);)* };
}
impl_uint!(u8 u16 u32 u64 u128 usize);
#[test]
fn test() {
for n in 1_u64..=30 {
for a in 0..30 {
let mut expected = 1 % n;
for b in 0..30 {
assert_eq!(a.mod_pow(b, n), expected);
expected = expected * a % n;
}
}
}
}