0

I am trying to solve "PRIME1"(http://www.spoj.com/problems/PRIME1/) on spoj. A lot of people are saying that I should solve it using Segmented Sieve of eratosthenes. I understood Sieve of eratosthenes but How I can implement Segmented one? I've seen all most all the resources and couldn't understand properly. This is the code I've written for Sieve of eratosthenes :

#include<stdio.h>
#include<math.h>
int main()
{
    long long int i,n,j,m;
    _Bool a[10000];
    scanf(" %lld",&n);
    for(i=2;i<=n;i++)
    {
        a[i]=1;
    }
    for(i=2;i<=sqrt(n);i++)
    {
        for(j=2;i*j<=n;j++)
        {
            a[i*j]=0;
        }
    }
    for(i=1;i<=n;i++)
    {
        if(a[i]==1)
            printf("%lld\n",i);
    }
  return 0;
}

From this, How can I implemet Segmented Sieve of eratosthenes. Please explain it in a beginner's perspective.

Vanu Aparna
  • 105
  • 8
  • @pzaenger : boolean data type. – Vanu Aparna Mar 23 '15 at 20:11
  • I know. But does this even compile? I mean, where do you get `_Bool` from? Because C does not know `_Bool`. And: is this C or C++? (I guess it is C) – pzaenger Mar 23 '15 at 20:12
  • Instead of creating a large array of arbitrary size, you should use `std::vector` or whatever bool type you are using, which can be dynamically sized. – Neil Kirk Mar 23 '15 at 20:13
  • @pzaenger: bool & _Bool are same. I have habit of writing it as _Bool. – Vanu Aparna Mar 23 '15 at 20:14
  • This is what happens if you tag C code as C++ – Neil Kirk Mar 23 '15 at 20:18
  • I explain the segmented Sieve of Eratosthenes at some length [elsewhere at Stack Overflow](http://stackoverflow.com/questions/10249378/segmented-sieve-of-eratosthenes/10249801#10249801). Includes pseudocode but not C. – user448810 Mar 23 '15 at 20:20

1 Answers1

1

The idea is very simple:

  • Start from k=2
  • Compute where you would fall in after entering the interval; this is simply x=((m + k - 1)/k)*k. For example for m=12345 and k=7 you get 12348 and that's the smallest multiple of 7 greater than or equal to m.
  • Mark the spot associated to x as "taken" and keep adding k to x until you get past n
  • Increment k and repeat until you get past sqrt(n)

You don't need to test all values for k but only prime numbers. For that you can use a normal sieve to compute all primes not bigger than sqrt(n) (note that sqrt(1000000000) < 31623 is not a really big number and there are only 3401 primes in that range).

Pay attention to not "marking" x at the start of the inner loop if it happens to be equal to k; the minimum value to consider for x is 2*k.

You can stop at sqrt(n) instead of n because if you have a composite number t<n with t=p*q with p>1 and q>1 then it must be either p<sqrt(n) or q<sqrt(n) and therefore the spot for t has already been marked when you stop at k=sqrt(n).

6502
  • 112,025
  • 15
  • 165
  • 265