线性筛法求质数
做法
-
用数组 (v) 来存储每个数的最小质因子
-
枚举2~n之间的数
-
若(v[i] == i) 则该数为质数,将其保存
-
穷举2~(v[i])的质数 (p) (不包含(v[i])),则(v[i*q]) = (q)
- 因为 (p) 小于(v[i]), 所以合数 (v[i*p]) 的最小质因子是 (p)
推论
-
从头往后挨个枚举,只要满足(v[i] = i),就加入prime[]
-
并把对应的(v[i*q](qle v[i]))更新,从而达到类似DP的动态类取数问题
-
(prime) 数组存储 (n) 中的质数,这样就可以打印出每一个质数啦
-
时间复杂度 (O(n))
Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
const int manx=1e8+10;
const int mamx = 1e6 + 11;
const int B = 1e6 + 11;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
inline int read() {
char c = getchar(); int x = 0, f = 1;
for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
return x * f;
}
int v[manx],prime[manx],m;
void primes(int n){
memset(v,0,sizeof(v));
m = 0;
for(int i = 2;i <= n; i++){
if(v[i] == 0){
v[i] = i;
prime[++m] = i;
}
for(int j = 1;j <= m; j++){
if(prime[j] > v[i] || prime[j] >n/i)break;//i有比prime[j]更小的因子,或者超出n的范围,则跳出循环
v[i*prime[j]] = prime[j];
}
}
//for(int i = 1;i <= m ;i++)cout<<prime[i]<<endl;
sort(prime + 1,prime + 1 + m);
}
int main(){
int n = read(),q = read();
primes(n);
for(int i = 1; i <= q; i++)
{
int x = read();
//cout<<prime[x]<<endl;
}
return 0;
}