prime_number_utils/
segmented_sieve.rs1use crate::{impl_gen_range, BitwiseSieve, GenPrime};
2use std::ops::{Bound::*, RangeBounds};
3
4#[derive(Default, Debug, Clone, Eq, PartialEq, Hash)]
15pub struct SegmentedSieve<G: GenPrime = BitwiseSieve> {
16 max: usize,
17 min: usize,
18 gen_prime: G,
19}
20
21impl<G: GenPrime> SegmentedSieve<G> {
22 pub fn new(gen_prime: G) -> Self {
24 Self {
25 max: 0,
26 min: 0,
27 gen_prime,
28 }
29 }
30}
31
32impl<G: GenPrime> GenPrime for SegmentedSieve<G> {
33 fn gen(&mut self) -> Vec<usize> {
34 if self.max < 2 {
35 return vec![];
36 }
37 let n = (self.max as f64).sqrt() as usize;
38 let mut primes = self.gen_prime.gen_range(0..n);
39 let mut low = n;
40 let mut high = 2 * n;
41 let mut result = vec![];
42 while low < self.max {
43 if high >= self.max {
44 high = self.max;
45 }
46 let mut sieve = vec![0; n];
47 for i in &primes {
48 let mut lolim = low / i * i;
49 if lolim < low {
50 lolim += i;
51 }
52 for j in (lolim..high).step_by(*i) {
53 sieve[j - low] = 1;
54 }
55 }
56 for i in low..high {
57 if sieve[i - low] == 0 {
58 result.push(i);
59 }
60 }
61 low += n;
62 high += n;
63 }
64 primes.append(&mut result);
65 primes
66 }
67
68 impl_gen_range!();
69}