-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodulo.rs
43 lines (38 loc) · 1006 Bytes
/
modulo.rs
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
use cargo_snippet::snippet;
// 繰り返し二乗法
#[snippet]
pub fn mod_pow(base: usize, exp: usize, modulo: usize) -> usize {
if exp == 0 {
return 1;
}
let base = base % modulo;
let mut result = mod_pow(base * base % modulo, exp / 2, modulo);
if exp % 2 == 1 {
result *= base;
result %= modulo;
}
result
}
// 逆元 num^(modulo-2) : mod modulo
// a*a^(p-2)≡1 : mod p
#[snippet(include = "mod_pow")]
pub fn mod_inv(num: usize, modulo: usize) -> usize {
mod_pow(num, modulo - 2, modulo)
}
#[cfg(test)]
mod tests {
use super::*;
const MOD: usize = 998244353;
#[test]
fn test_mod_pow() {
assert_eq!(mod_pow(10, 0, MOD), 1);
assert_eq!(mod_pow(10, 3, MOD), 1000);
assert_eq!(mod_pow(10, 10, MOD), 17556470);
assert_eq!(mod_pow(MOD * MOD + 10, 3, MOD), 1000);
}
#[test]
fn test_mod_inv() {
assert_eq!(mod_inv(7, 13), 2);
assert_eq!(mod_inv(2, MOD), 499122177);
}
}