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