欧拉筛是一种用于筛出质数的算法。

欧拉筛的时间复杂度为O(n),其实现主要依赖于,对任意一个合数p,只通过其最小的约数筛掉。实现过程如下:

1.首先建st数组和primes数组,st数组中st[i]表示整数i是否为质数,primes数组记录所有的素数
2.循环遍历,设当前的数为p,如果st[p]false,则表示p为质数,加入primes数组中
3.遍历primes数组,筛掉iprimes[j],如果i%primes[j]=0则提前结束循环(注1)

注1:对于a=primes[j]i,假设a可以被表示为p1p2...pn其中p1p2...pn,若i%primes[j]=0,
则表明primes[j]是i的一个因子,又由于是i的一个因子,所以显然i/primes[j]也是a的一个因子,故ai=i或者更
早的时候就已经被筛掉,所以此时break掉保证了一个数只会被其最小的因子筛掉。(例,24=2223,理论
上,当i=8时,就会被83筛掉,而到i=12的时候,由于12%2=0,所以会直接退出循环,保证了24不被重复筛掉)

代码如下:(这个是Acwing上的题目)


using namespace std;

const int N = 1000010;

int st[N],primes[N];
int get_primes(int x){
    int cnt = 0;
    for(int i = 2;i <= x;i++){
        if(!st[i]) primes[++cnt] = i; //如果i是质数,就添加到primes数组中
        for(int j = 1;i * primes[j] <= x;j++){
            st[i * primes[j]] = true; //筛掉i*primes[j]
            if(i % primes[j] == 0) break;//保证一个数不会被反复筛掉
        }
    }
    return cnt;
}
int main(){
    int n; cin >> n;
    printf("%d\n",get_primes(n));
    return 0;
}