1pub mod fft;
3pub mod num;
4
5pub fn extended_gcd(a: i64, b: i64) -> (i64, i64, i64) {
7 if b == 0 {
8 (a.abs(), a.signum(), 0)
9 } else {
10 let (d, coef_b, coef_a) = extended_gcd(b, a % b);
11 (d, coef_a, coef_b - coef_a * (a / b))
12 }
13}
14
15pub fn canon_egcd(a: i64, b: i64, c: i64) -> Option<(i64, i64, i64)> {
21 let (d, _, coef_b_init) = extended_gcd(a, b);
22 if c % d == 0 {
23 let a_d = (a / d).abs();
24 let coef_b = (coef_b_init * (c / d) % a_d + a_d) % a_d;
25 let coef_a = (c - b * coef_b) / a;
26 Some((d, coef_a, coef_b))
27 } else {
28 None
29 }
30}
31
32fn pos_mod(n: i64, m: i64) -> i64 {
34 if n < 0 {
35 n + m
36 } else {
37 n
38 }
39}
40fn mod_mul(a: i64, b: i64, m: i64) -> i64 {
41 pos_mod((a as i128 * b as i128 % m as i128) as i64, m)
42}
43fn mod_exp(mut base: i64, mut exp: u64, m: i64) -> i64 {
44 assert!(m >= 1);
45 let mut ans = 1 % m;
46 base %= m;
47 while exp > 0 {
48 if exp % 2 == 1 {
49 ans = mod_mul(ans, base, m);
50 }
51 base = mod_mul(base, base, m);
52 exp /= 2;
53 }
54 pos_mod(ans, m)
55}
56
57fn is_strong_probable_prime(n: i64, exp: u64, r: i64, a: i64) -> bool {
58 let mut x = mod_exp(a, exp, n);
59 if x == 1 || x == n - 1 {
60 return true;
61 }
62 for _ in 1..r {
63 x = mod_mul(x, x, n);
64 if x == n - 1 {
65 return true;
66 }
67 }
68 false
69}
70
71pub fn is_prime(n: i64) -> bool {
73 const BASES: [i64; 12] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37];
74 assert!(n >= 0);
75 match n {
76 0 | 1 => false,
77 2 | 3 => true,
78 _ if n % 2 == 0 => false,
79 _ => {
80 let r = (n - 1).trailing_zeros() as i64;
81 let exp = (n - 1) as u64 >> r;
82 BASES
83 .iter()
84 .all(|&base| base > n - 2 || is_strong_probable_prime(n, exp, r, base))
85 }
86 }
87}
88
89fn pollard_rho(n: i64) -> i64 {
90 for a in 1..n {
91 let f = |x| pos_mod(mod_mul(x, x, n) + a, n);
92 let mut x = 2;
93 let mut y = 2;
94 loop {
95 x = f(x);
96 y = f(f(y));
97 let div = num::fast_gcd(x - y, n);
98 if div == n {
99 break;
100 } else if div > 1 {
101 return div;
102 }
103 }
104 }
105 panic!("No divisor found!");
106}
107
108pub fn factorize(n: i64) -> Vec<i64> {
111 assert!(n >= 1);
112 let r = n.trailing_zeros() as usize;
113 let mut factors = vec![2; r];
114 let mut stack = match n >> r {
115 1 => vec![],
116 x => vec![x],
117 };
118 while let Some(top) = stack.pop() {
119 if is_prime(top) {
120 factors.push(top);
121 } else {
122 let div = pollard_rho(top);
123 stack.push(div);
124 stack.push(top / div);
125 }
126 }
127 factors.sort_unstable();
128 factors
129}
130
131#[cfg(test)]
132mod test {
133 use super::*;
134
135 #[test]
136 fn test_egcd() {
137 let (a, b) = (14, 35);
138
139 let (d, x, y) = extended_gcd(a, b);
140 assert_eq!(d, 7);
141 assert_eq!(a * x + b * y, d);
142
143 assert_eq!(canon_egcd(a, b, d), Some((d, -2, 1)));
144 assert_eq!(canon_egcd(b, a, d), Some((d, -1, 3)));
145 }
146
147 #[test]
148 fn test_modexp() {
149 let m = 1_000_000_007;
150 assert_eq!(mod_exp(0, 0, m), 1);
151 assert_eq!(mod_exp(0, 1, m), 0);
152 assert_eq!(mod_exp(0, 10, m), 0);
153 assert_eq!(mod_exp(123, 456, m), 565291922);
154 }
155
156 #[test]
157 fn test_miller() {
158 assert_eq!(is_prime(2), true);
159 assert_eq!(is_prime(4), false);
160 assert_eq!(is_prime(6), false);
161 assert_eq!(is_prime(8), false);
162 assert_eq!(is_prime(269), true);
163 assert_eq!(is_prime(1000), false);
164 assert_eq!(is_prime(1_000_000_007), true);
165 assert_eq!(is_prime((1 << 61) - 1), true);
166 assert_eq!(is_prime(7156857700403137441), false);
167 }
168
169 #[test]
170 fn test_pollard() {
171 assert_eq!(factorize(1), vec![]);
172 assert_eq!(factorize(2), vec![2]);
173 assert_eq!(factorize(4), vec![2, 2]);
174 assert_eq!(factorize(12), vec![2, 2, 3]);
175 assert_eq!(
176 factorize(7156857700403137441),
177 vec![11, 13, 17, 19, 29, 37, 41, 43, 61, 97, 109, 127]
178 );
179 }
180}