标签:埃氏筛法 i++ std 质因数分解 es2017 数论 while 线性 有一个
1.素数筛(线筛):
时间复杂度为O(n),可以筛选出n以内的所有素数,共有tot个,prime[x]==true,则x是素数
筛选原理:
任意一个数乘以比它小的素数的结果都是合数
遇到最小质因子就跳出循环,保证每个合数被其最小质因子筛去
附上代码:
1 #include<cstdio> 2 const int N = 100000 + 5; 3 bool prime[N];//prime[i]表示i是不是质数 4 int p[N], tot=0;//p[N]用来存质数,tot为素数的个数 5 void init(int n){ 6 prime[1]=false; 7 for(int i = 2; i <=n; i ++) prime[i] = true;//初始化为质数 8 for(int i = 2; i <=n; i++){ 9 if(prime[i]) p[tot ++] = i;//把质数存起来 10 for(int j = 0; j < tot && i * p[j] <=n; j++){ 11 prime[i * p[j]] = false; 12 if(i % p[j] == 0) break;//保证每个合数被它最小的质因数筛去 13 } 14 } 15 } 16 int main(){ 17 init(11); 18 for(int i=0;i<tot;i++) 19 printf("%d\n",p[i]); 20 printf("tot=%d\n",tot); 21 }
利用了每个合数必有一个最小素因子。每个合数仅被它的最小素因子筛去正好一次。所以为线性时间。
2.埃筛--------------埃拉托斯特尼筛法,或者叫埃氏筛法
原理:
任意一个素数的倍数都是合数
过程图解:
代码也很好写:
1 #include<cstdio> 2 const int N = 100000 + 5; 3 bool prime[N]; 4 void init(){ 5 for(int i = 2; i <= N; i ++) prime[i] = true; 6 for(int i = 2; i*i <= N; i ++){//判断改成i*i<N 7 if(prime[i]){ 8 for(int j = i*i; j <= N; j += i){//从i*i开始就可以了 9 prime[j] = false; 10 } 11 } 12 } 13 } 14 int main(){ 15 init(); 16 }
时间复杂度为O(n*loglog n),因为loglog n非常小,基本上和线筛无区别,较常用
(还有个规律,除了2,3,其他的素数一定在6的倍数的旁边,ji
基于埃筛的原理,我们可以用它干很多事
3.预处理每个数的所有质因数:
1 #include<cstdio> 2 #include<vector> 3 using namespace std; 4 const int N = 100000 + 5; 5 vector<int > prime_factor[N]; 6 void init(){ 7 for(int i = 2; i <= N; i ++){ 8 if(prime_factor[i].size() == 0){//如果i是质数 9 for(int j = i; j <= N; j += i){ 10 prime_factor[j].push_back(i); 11 } 12 } 13 } 14 } 15 int main(){ 16 init(); 17 for(int i=0;i<prime_factor[60].size();i++) 18 printf("%d ",prime_factor[60][i]);//60的所有素因子 19 }
如果把判断i是质数的判断(第8行),则是预处理每个数的因数
4.预处理每个数的质因数分解
1 #include<cstdio> 2 #include<vector> 3 using namespace std; 4 const int N = 100000 + 5; 5 vector<int > prime_factor[N]; 6 void init(){ 7 int temp; 8 for(int i = 2; i < N; i ++){ 9 if(prime_factor[i].size() == 0){ 10 for(int j = i; j < N; j += i){ 11 temp = j; 12 while(temp % i == 0){ 13 prime_factor[j].push_back(i); 14 temp /= i; 15 } 16 } 17 } 18 } 19 } 20 int main(){ 21 init(); 22 for(int i=0;i<prime_factor[60].size();i++) 23 printf("%d ",prime_factor[60][i]); 24 }
标签:埃氏筛法 i++ std 质因数分解 es2017 数论 while 线性 有一个
原文地址:http://www.cnblogs.com/eastblue/p/7617277.html