• 每次保证一个合数只会被最小质因子筛一次。
  • 两种情况:
    当i % pirme[j] == 0 , 由于我们是从小到大枚举的,当取余等于0时代表肯定是最小的质因子,那么 i * prime[j] 的 最小质因子也是prime[j]。 然后就可以退出循环了。
    当i % prime[j] != 0, 代表prime[j] 不是i的质因子,但是它一定是比i最小质因子还小的质数,那么 i * prime[j] 的最小质因子也是prime[j]。
#include <cstdio>
const int N = 1e7 + 5;
bool is_prime[N]; 
int n, cnt, prime[N];
void f() { 
	is_prime[1] = true;
	for (int i = 2; i <= n ; i++) {
		if (!is_prime[i]) prime[cnt++] = i;
		for (int j = 0; prime[j] <= n / i; j ++) {
			is_prime[i * prime[j]] = 1;
			if (i % prime[j] == 0) break;
		}
	}
}
int main() {
	scanf("%d", &n);
	f();
	printf("%d", cnt);
	return 0;
}