mod math {
use itertools::Itertools;
use num_integer::Roots;
pub struct SieveEratosthenes {
min_fact: Vec<u32>,
}
impl SieveEratosthenes {
pub fn new(n: usize) -> Self {
Self::build(n)
}
fn build(n: usize) -> Self {
let mut min_fact = (0..=n as u32).collect_vec();
min_fact[1] = 0;
for i in 2..=n.sqrt() {
for j in (i * i..=n).step_by(i) {
min_fact[j] = min_fact[j].min(i as u32);
}
}
Self { min_fact }
}
pub fn is_prime(&self, x: u32) -> bool {
if x < 2 {
false
} else {
self.min_fact[x as usize] == x
}
}
pub fn factorize(&self, mut x: u32) -> Vec<(u32, usize)> {
let mut ret = vec![];
while x > 1 {
if ret.last().unwrap_or(&(0, 0)).0 == self.min_fact[x as usize] {
ret.last_mut().unwrap().1 += 1;
} else {
ret.push((self.min_fact[x as usize], 1));
}
x /= self.min_fact[x as usize];
}
ret
}
}
}