快速線性篩求素數問題

NO1ios

快速線性篩求素數問題(歐拉篩法)

 

特色:沒有冗餘,不會重複篩除一個數。 其時間複雜度幾乎爲O(n)。spa

原理:對於任意合數,一定能夠有最小質因子乘以最大因子的分解方式。所以,對於每一個合數,只要用最大因子篩一遍,枚舉時只要枚舉最小質因子便可。code

 1 #include<iostream>
 2 #define MAXN 1000010
 3 using namespace std;
 4 long prime[MAXN],number_prime;  //prime 爲素數的集合,number_prime 爲素數的個數
 5 bool vis[MAXN];  //vis 用於記錄那些數不是素數
 6 inline void pd_prime(int number)  //number 是所求素數集合的上限
 7 {
 8     for(int i=2;i<=number;i++)
 9     {
10         if(!vis[i]) prime[number_prime++]=i;  //若是不在 非素數集合內 斷定爲素數--同時 number+1 (此時是number先賦值再+1,故prime序列從0開始)
11         for(int j=0;j<number_prime && i*prime[j]<=number;j++)  //j要小於如今求出來的素數個數,而且下一步篩出的那個數(i*某已知素數要小於要求的上限)
12         {
13             vis[i*prime[j]]=true;  //能拆成 i*質數 爲合數 篩出
14             if(!(i%prime[j])) break;  //見註解1 i%prime[j]==0
15         }
16     }
17 }
18 int main()
19 {
20     int n;
21     cin>>n;
22     pd_prime(n);
23     for(int i=0;i<number_prime;i++) cout<<prime[i]<<endl;
24     cout<<endl<<"total number: "<<number_prime;
25     return 0;
26 }

註解1:只篩最小質因子blog

eg: 12=2*2*3ci

當 i=4 時,將 4*2 篩除---中止io

......class

當i=6時,將 6*2 篩除---6*3 篩除---中止stream

12的最小質因子爲 2,只在 i=2 時篩了一遍原理

若 i=p1*p2*......*pn  設p2*......*pn 爲q 則只篩除 x=i*p1 即 x= p1 * p1 *q。其他的合數 如: x2=p2*p1*q = (p2 * p2* ...... *pn) * p1; 在 i=(p2 * p2* ...... *pn) 時天然會篩除。im

相關文章
相關標籤/搜索