eratosthenes算法的分段筛

时间:2015-03-23 20:08:28

标签: c primes sieve-of-eratosthenes

我正在尝试在spoj上解决“PRIME1”(http://www.spoj.com/problems/PRIME1/)。 很多人都说我应该使用eratosthenes的分段筛来解决它。我理解了eratosthenes的Sieve但我如何实现Segmented one?我已经看到了所有的资源,并且无法正确理解。 这是我为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;
}

由此,我如何实施eratosthenes的分段筛。请从初学者的角度解释。

1 个答案:

答案 0 :(得分:1)

这个想法非常简单:

  • k=2
  • 开始
  • 计算进入间隔后你会落入的地方;这只是x=((m + k - 1)/k)*k。例如,对于m=12345k=7,您获得的是12348,而7的最小倍数大于或等于m
  • 将与x相关联的地点标记为&#34;采取&#34;并继续将k添加到x,直到您超过n
  • 递增k并重复,直到您超过sqrt(n)

您不需要测试k的所有值,只需测试素数。为此,您可以使用普通筛来计算不大于sqrt(n)的所有素数(请注意sqrt(1000000000) < 31623不是一个非常大的数字,并且该范围内只有3401个素数。)

注意不要&#34;标记&#34;如果它恰好等于x,则在内循环开始时为k; x要考虑的最小值是2*k

您可以停在sqrt(n)而不是n,因为如果您的t<n合并后的t=p*q合并p>1q>1,那么它必须是p<sqrt(n)q<sqrt(n),因此当您在t停留时,k=sqrt(n)的地点已被标记。