AtCoder Beginner Contest 300 D

https://atcoder.jp/contests/abc300/tasks/abc300_d

しらみつぶしで十分ですね。
エラトステネスの篩を実装してみました。

// AABCC
#![allow(non_snake_case)]

//////////////////// library ////////////////////

fn read<T: std::str::FromStr>() -> T {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).ok();
    line.trim().parse().ok().unwrap()
}

fn make_prime_table(N: usize) -> Vec<usize> {
    let mut a: Vec<bool> = (0..N+1).map(|_| true).collect();
    for p in 2usize.. {
        if p * p > N {
            break
        }
        else if !a[p] {
            continue
        }
        for m in (p*p..N+1).step_by(p) {
            a[m] = false
        }
    }
    (2..N+1).filter(|&n| a[n]).collect::<Vec<usize>>()
}


//////////////////// process ////////////////////

fn f(N: usize) -> usize {
    let ps = make_prime_table(((N/12) as f64).sqrt() as usize);
    let mut counter: usize = 0;
    for i in 0..ps.len()-2 {
        let a = ps[i];
        if a * a * ps[i+1] * ps[i+2] * ps[i+2] > N {
            break
        }
        let M = N / (a * a);
        for j in i+1..ps.len()-1 {
            let b = ps[j];
            if b * ps[j+1] * ps[j+1] > M {
                break
            }
            let L = M / b;
            for k in j+1..ps.len() {
                let c = ps[k];
                if c * c > L {
                    break
                }
                counter += 1
            }
        }
    }
    counter
}

//////////////////// main ////////////////////

fn main() {
    let N: usize = read();
    println!("{}", f(N))
}