先来说一说N方筛素数
a[1]=1;
for (int i=2;i<=n;i++) { if (a[i]==0) for (int j=2;j<=n/i;j++) a[i*j]=1;
}
线性筛素数和N方筛素数最大的差别就在于线性筛素数可以同过i%prime[j]来达到线性,其本质的思想就是用最小质因数来筛。
先上代码:
a[1]=1;pri=0; for (int i=2;i<=n;i++) { if (!a[i]) prime[++pri]=i; for (int j=1;j<=pri && i*prime[j]<=n;j++) { a[i*prime[j]]=1; a[1]=1;pri=0; for (int i=2;i<=n;i++) { if (!a[i]) prime[++pri]=i; for (int j=1;j<=pri && i*prime[j]<=n;j++) { a[i*prime[j]]=1; if (!(i%prime[j]))break; } } }证明一下下面这段代码的正确性
if (!(i%prime[j]))break;
对于任意数正数A,若A=x*y(其中x为素数,y为合数)
且y=a*b(其中a为素数)
如果a<x则有A=x*a*b=a*Z(Z=a*b)
也就是说一个合数如果可以分解为一个质数与一个合数,而且它可以分解为一个跟小的质数和一个更大的合数,那么我们会用更小的那个素数来筛出合数,即A是由a筛出来的而不是x,所以当i是一个质数a的倍数时会退出循环,因为这次扩展出的合数会在以后选到,比如:20不是由5筛出来的,而是由2筛出来的。