质数筛选

1.埃式筛选法

从2开始向后枚举每个数的倍数,将其筛选去除,e.g:(2,3,4........p-1)若这个区间里没有任何一个数的倍数是p,则p一定是质数

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string.h>
 5 #include <math.h>
 6 #include <algorithm>
 7 #include <stack>
 8 #include <queue>
 9 #include <vector>
10 #include <map>
11 #include <set>
12 #define ll long long
13 const int N=1e6+10;
14 using namespace std;
15 typedef pair<int,int>PII;
16 
17 int cnt;
18 bool st[N];
19 
20 void sieve_prime(int n){
21     for(int i=2;i<=n;++i){
22       if(!st[i]){
23          cnt++;
24          for(int j=i+i;j<=n;j+=i) st[j]=true;
25       }
26     }
27 }
28 
29 int main(){
30  ios::sync_with_stdio(false);
31   int n;
32    cin>>n;
33     sieve_prime(n);
34 
35     printf("%d\n",cnt);
36   return 0;
37 }

2.欧拉筛(线性筛)

 我们利用每个合数的最小质因数来进行筛选,i相当于是倍数,如果i%prime[j]==0,那么prime[j]一定是i*prime[j]这个合数的最小质因数,如果i%prime[j]!=0,那么prime[j]也同样还是这个合数的最小质因数(primep[j]比i的任何一个质因数都小)

2020/7/23日补:我们每次去找合数,都是用它的最小质因子来找的,那么我们要实现这个,就要求要在i%prime[j]=0的时候break,因为prime[j]一定是质数,所以它是i的质因子,那么我们再用i去找后面的合数之时,其最小质因子就会是我i%prime[j]=0,时的这个质数,而不是我们当前所枚举的这个质数.

这儿顺便附上一个:https://www.luogu.com.cn/problemnew/solution/P3383,这儿有更加详细的解释

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <stack>
 7 #include <queue>
 8 #include <vector>
 9 #include <map>
10 #include <set>
11 #include <unordered_set>
12 #include <unordered_map>
13 #define ll long long
14 #define fi first
15 #define se second
16 #define pb push_back
17 #define me memset
18 const int N = 1e8 + 10;
19 const int M = 1e9 + 7;
20 using namespace std;
21 typedef pair<int,int> PII;
22 typedef pair<long,long> PLL;
23 int n,q,k;
24 int prime[N],cnt;
25 bool st[N];
26 
27 void get_prime(int n){
28     for(int i=2;i<=n;++i){
29         if(!st[i]) prime[cnt++]=i;
30          for(int j=0;j<cnt && prime[j]<=n/i;++j){
31              st[i*prime[j]]=true;    //一定能保证prime[j]是i*prime[j]的因数
32              if(i%prime[j]==0) break;
33          }
34     }
35 }
36 
37 int main() {
38     ios::sync_with_stdio(false);
39    cin>>n>>q;
40    get_prime(n);
41     while(q--){
42         cin>>k;
43          printf("%d\n",prime[k-1]);
44     }
45     return 0;
46 }
原文地址:https://www.cnblogs.com/lr599909928/p/12635519.html