Solved Problem - Segmented Sieve

In this lesson, we'll discuss how to implement the segmented Sieve: a very popular variation of sieve.

Problem statement

Given two integers, NN and MM, print all primes between NN and MM (both inclusive).

Input format

The only line of input contains two integers NN and MM (1NM109)(MN106)(1 \leq N \leq M \leq 10^9)( M-N \leq 10^6).


Sample

Input

100000000 100000100

Output

100000007 100000037 100000039 100000049 100000073 100000081

Sieve

Obviously, Sieve of Eratosthenes comes to mind. Now, two things don’t work right here:

  1. M<=109M <= 10^9, we don’t have enough memory to declare an array of a billion integers (4 GB memory).
  2. Even if we could declare an array that big, the time complexity would be O(Mlog(logM))O(M*log(logM)), which is obviously very slow.

Observation: MN<=106M - N <= 10^6


Segmented sieve

Since the range in which we want the generate the primes is at max 10610^6, we can run a modified version of sieve on a Boolean array A[]A[] of size MN+1M-N+1 such that.

  • A[0]A[0] - denotes whether NN is prime or not.
  • A[1]A[1] - denotes whether N+1N+1 is prime or not.
  • A[MN]A[M-N] - denotes whether MM is prime or not.

Marking multiples not-prime

Comparing to sieve where we iterate up to N\sqrt{N} and if the current number is prime, we mark its multiples not-prime.

Here, we will iterate up to M\sqrt{M}, but if the number doesn’t belong in the range [N,M][N, M], we don’t know if it’s a prime or not. So, in this case, we will mark multiples not-prime for all the numbers in [2,(M)][2, \sqrt(M)].

We only need to mark the multiples if the multiple is between NN and MM. To do this, we start with the first multiple of this number that is greater than or equal to NN.

First multiplex of xx just greater than or equal to NN can be calculated as follow:

m=(N1x+1)xm = (\lfloor\frac{N-1}{x}\rfloor + 1) * x

Get hands-on with 1200+ tech skills courses.