欧拉筛法求素数
首先要说明一些数学知识
一个数可以分成两个数的乘积,即c=ab。其中当a为c的最小质因子时,对于任意的c,显然若a相同,则b必定各不相同;若a不相同则b可能相同或不相同。所以c=ab中,任意两个的c分解出来的a和b至少有一个不相同,即a不相同或者b不相同。
总结:只要a是c的最小质因子数,每次以a*b的形式去筛除c,且在a相同时b不相同,则就可以保证c只被筛除一次。
通过每一次循环将以su[j]作为最小质因数,筛除i*su[j]。当i%su[j]==0时,则i=su[j]某个数x,假设x可以分解出小于su[j]的质因子,那么必然在之前的循环中满足i%su[j]==0,跳出循环了。所以x的所有质因子必然大于su[j],因此保证了每次筛除中su[j]是isu[j]的最小质因子数。所以每个合数只被筛除一次。
// 欧拉筛法求素数
#include<iostream>
#include<cstdio>
using namespace std;
#define N 1000010
int vi[N],su[N],cnt=0,n;
void print(int n){
for(int i=2;i<=n;i++)
{
if(vi[i]==0)
printf("%d ",i);
}
}
int main() {
scanf("%d",&n);
for(int i=2;i<=n;i++)
{
if(vi[i]==0)
su[cnt++]=i;
for(int j=0;j<cnt&&i*su[j]<=n;j++)
{
vi[i*su[j]]=1;
if(i%su[j]==0)
break;
}
}
print(n);
return 0;
}