线性筛法的思想:让每个数被他的最小质因子给筛去
举例: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
比如这个24,我们要让他被2筛去,因为2是他的最小质因子
和原来的埃式筛法,有什么优化呢?
埃式筛法会有很多数字有打多次标记,大量重复,而通过最小质因子每个合数只会被他的最小质因子的倍数筛去1次。
对代码的解释:primes[j]<=n/i
primes[]存的是最小质因子,同时也是递增的.primes[j]*i<=n。
因为要筛去的是n以内的primes[j]的i倍,如果超出n就没意义了
if(i%primes[j]==0) break;什么意思?
我们假设如果不进行break,已有primes[j]|i
。 那么程序进行primes[j+1]*i==true;
但是primes[j]|primes[j+1]*i
就会导致不是最小质因子筛去.
举例: _24%2==0;应该让24由最小质因子2筛去,此时i需要等于12.但是由于不break,那么可以被下一个质因子3X8提前筛去,不满足刚开始的思想(由最小质因子筛去) _
C++
#include<iostream>
#include<algorithm>
using namespace std;
int const maxn=1000010;
int primes[maxn],ans;
bool st[maxn];
int main(void)
{
int n;cin>>n;
for(int i=2;i<=n;i++)
{
if(!st[i]) primes[ans++]=i;
for(int j=0;primes[j]<=n/i;j++)
{
st[primes[j]*i]=true;
if(i%primes[j]==0) break;
}
}
cout<<ans<<endl;
return 0;
}