我正在尝试在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的分段筛。请从初学者的角度解释。
答案 0 :(得分:1)
这个想法非常简单:
k=2
x=((m + k - 1)/k)*k
。例如,对于m=12345
和k=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>1
和q>1
,那么它必须是p<sqrt(n)
或q<sqrt(n)
,因此当您在t
停留时,k=sqrt(n)
的地点已被标记。