#include <stdio.h>
#include <stdlib.h>
#define MAX_N 1000000
// 声明一个质数计数数组
int prime_count[MAX_N + 1];
// 埃拉托斯特尼筛法
void sieve_of_eratosthenes() {
// 初始化质数数组,默认所有数都认为是质数
int is_prime[MAX_N + 1];
for (int i = 0; i <= MAX_N; i++) {
is_prime[i] = 1; // 假设所有数都是质数
}
is_prime[0] = is_prime[1] = 0; // 0和1不是质数
// 埃拉托斯特尼筛法
for (int i = 2; i * i <= MAX_N; i++) {
if (is_prime[i]) {
for (int j = i * i; j <= MAX_N; j += i) {
is_prime[j] = 0;
}
}
}
// 计算每个数小于等于它的质数个数
prime_count[0] = 0;
for (int i = 1; i <= MAX_N; i++) {
prime_count[i] = prime_count[i - 1] + is_prime[i];
}
}
int main() {
int T;
scanf("%d", &T); // 读取查询次数
// 预处理所有质数信息
sieve_of_eratosthenes();
// 对于每个查询,输出小于等于n的质数个数
while (T--) {
int n;
scanf("%d", &n);
printf("%d\n", prime_count[n]);
}
return 0;
}
代码解析:
-
sieve_of_eratosthenes():
- 该函数使用埃拉托斯特尼筛法来标记质数。我们维护一个is_prime数组来标记每个数是否为质数。
- 对于每个质数 p,标记 p^2, p^2 + p, p^2 + 2p,… 为非质数。
- 然后,使用prime_count数组来记录每个数小于等于它的质数个数。
-
main():
- 首先读取查询次数T。
- 然后对每个查询n,直接输出prime_count[n],这表示小于等于n的质数个数。
时间复杂度:
- 埃拉托斯特尼筛法:时间复杂度为 O(nloglogn),其中 n= 10^6。
- 查询阶段:每次查询的时间复杂度是 O(1),因为我们直接查找预处理结果。
空间复杂度:
- 需要 O(n)的空间来存储is_prime和prime_count数组,最多需要 10^6 个元素。



京公网安备 11010502036488号