质数筛选

1.埃及筛选法

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

代码:

 1 #include 
 2 #include 
 3 #include 
 4 #include <string.h>
 5 #include 
 6 #include 
 7 #include 
 8 #include 
 9 #include 
10 #include 
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,那么i*prime[j]也同样还是这个合数的最小质因数(primep[j]比i的任何一个质因数都小)

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

代码:

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 6 #include 
 7 #include 
 8 #include 
 9 #include 
10 #include <set>
11 #include 
12 #include 
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;jj){
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 }

 

你可能感兴趣的:(质数筛选)