洛谷P3383 欧拉线性筛素数
题目:


先讲算法原理:
- 任何一个合数都存在唯一的最小质因子,
- 对于从小到大枚举的质数pj,如果\(i\%pj == 0\)则pj一定是\(i*pj\)的最小质因子
如果\(i\%pj != 0\)则pj一定是\(i*pj\)的最小质因子
对于任何一个合数,我们都使用它的最小质因子去筛它(是或者不是),因为每个合数只有一个最小质因子,所以它的时间复杂度是O(n)的
#include <cstdio>
using namespace std;
int n, q, k;
constexpr int N = 1e6 + 10;
bool st[N];
int primes[N];
int idx = 0;
inline void init(int n) {
memset(st, false, sizeof st);
// ouler
for(int i = 2; i <= n; ++i) {
if(!st[i]) {
primes[idx++] = i;
}
for(int j = 0; primes[j] <= n / i; ++j) {
st[primes[j] * i] = true;
if(i % primes[j] == 0) {
break; // 此处保证了前面i*primes[j]中的primes[j]不是i的质因子,因此i*primes[j]的最小质因子是primes[j]
}
}
}
}
int main() {
scanf("%d%d", &n, &q);
init(n);
for(int j = 0; j < q; ++j) {
scanf("%d", &k);
printf("%d\n", primes[k - 1]);
}
}

浙公网安备 33010602011771号