wenbao与筛法素数及判断模板

Posted wenbao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了wenbao与筛法素数及判断模板相关的知识,希望对你有一定的参考价值。

 1 #define ll long long 
 2 const int maxn = 1000000;
 3 int vis[maxn],prime[maxn];
 4 void isprime()
 5 {   
 6     memset(vis,0,sizeof(vis));
 7     ll cot=0,i,j;
 8     for( i=2;i<=1000000;i++)
 9     {
10         if(!vis[i])
11         {
12             prime[cot++]=i;
13             for( j=i*i;j<1000000;j+=i)
14             vis[j]=1;
15         }
16     }
17 }

 判断模板

 1 bool prime(int x)
 2 {
 3     if(x==2)
 4         return true;
 5     if(x%2==0||x==1)
 6         return false;
 7     bool flag=true;
 8     int t=(int )sqrt((double)x);
 9     for(int i=3; i<=t; i+=2)
10         if(x%i==0)
11         {
12             flag=false;
13             break;
14         }
15     return flag;
16 }

 

 

 

http://blog.csdn.net/lerenceray/article/details/12420725

 

 1 #include<cstring>
 2 #include<iostream>
 3 #include<ctime>
 4 using namespace std;
 5 #define N 100000005
 6 
 7 bool vis[N];
 8 int p[N], cnt, phi[N];
 9 
10 int Euler(int n){
11     int i, j, k;
12     phi[1] = 1;
13     for (i = 2; i < n; ++i){
14         if (!vis[i]){
15             p[cnt++] = i;
16             phi[i] = i - 1;
17         }
18         for (j = 0; j < cnt && i * p[j] < n; ++j){
19             vis[i * p[j]] = true;
20             if (i % p[j]) phi[i * p[j]] = phi[i] * phi[p[j]];
21             else {
22                 phi[i * p[j]] = phi[i] * p[j];
23                 break;
24             }
25         }
26     }
27     return cnt;
28 }
29 
30 int Eratosthenes (int n){
31         int i, j, k;
32         phi[1] = 1;
33         for (i = 2; i < n; ++i){
34                 if (!vis[i]) p[cnt++] = i;
35                 for (j = i; j < n; j += i) {
36                         if (!phi[j]) phi[j] = j;
37                         phi[j] = phi[j] / i * (i - 1);
38                         vis[j] = true;
39                 }
40         }
41         return cnt;
42 }
43 
44 int main(){
45         clock_t st, en;
46         int num;
47         double sec;
48         for (int t = 10; t < N; t *= 10){
49                 cout << t << : << endl;
50                 st = clock();
51                 num = Euler(t);
52                 en = clock();
53                 sec = (double)(en - st) / (double) CLOCKS_PER_SEC;
54                 //cout << "Euler : " << cnt << ‘ ‘ << sec << endl;
55                 printf("Euler :\t\t%8d\t%.8lf\n", num, sec);
56                 memset(vis, 0, sizeof(vis)), memset(p, 0, sizeof(p)), memset(phi, 0, sizeof(phi)), cnt = 0;
57                 st = clock();
58                 num = Eratosthenes(t);
59                 en = clock();
60                 sec = (double)(en - st) / (double) CLOCKS_PER_SEC;
61                 //cout << "Eratosthenes : " << cnt << ‘ ‘ << sec << endl;
62                 printf("Eratosthenes :\t%8d\t%.8lf\n", num, sec);
63         }
64         return 0;
65 }

 

 

http://www.bubuko.com/infodetail-837565.html

 

 

我们先来看一下最经典的埃拉特斯特尼筛法。时间复杂度为O(n loglog n)

 1 int ans[MAXN];
 2 void Prime(int n)
 3 {
 4     int cnt=0;
 5     memset(prime,1,sizeof(prime));
 6     prime[0]=prime[1]=0;
 7     for(int i=2;i<n;i++)
 8     {
 9         if(vis[i])
10         {
11            ans[cnt++]=i;//保存素数 
12            for(int j=i*i;j<n;j+=i)//i*i开始进行了稍微的优化
13            prime[j]=0;//不是素数 
14         }
15     }
16     return ;
17 }

 

显然,当一个数是素数的时候,那么他的倍数肯定是合数,筛选标记即可。从i*i而不从i*2开始,是因为已经i*3,i*2早已经被2,3筛过了。

 

由此,我们也可以发现有的合数被重复筛除,例如30,2*15筛了一次,5*6重复筛除,所以也就有了我们下面要提到的欧拉线性筛法。

不会重复筛除,是线性O(n)的复杂度。

 

 1 const int MAXN=3000001;
 2 int prime[MAXN];//保存素数 
 3 bool vis[MAXN];//初始化 
 4 void Prime(int n)
 5 {
 6     int cnt=0;
 7     memset(vis,0,sizeof(vis));
 8     for(int i=2;i<n;i++)
 9     {
10         if(!vis[i])
11         prime[cnt++]=i;
12         for(int j=0;j<cnt&&i*prime[j]<n;j++)
13         {
14             vis[i*prime[j]]=1;
15             if(i%prime[j]==0)//关键 
16             break;
17         }
18     }
19     return cnt;//返回小于n的素数的个数 
20 }

 

 

 1 void prime(){
 2     a[0] = a[1] = 1;
 3     for(int i = 2; i < maxn; i++){
 4         if(!a[i]){
 5             b[num] = i, num++;
 6         }
 7         for(int j = 0; j < num && i*b[j] < maxn; j++){
 8             a[i*b[j]] = 1;
 9             if(i%b[j] == 0) break;
10         }
11     }
12 }

 

 

 

只有不断学习才能进步!

 

以上是关于wenbao与筛法素数及判断模板的主要内容,如果未能解决你的问题,请参考以下文章

专题素数的判定与筛法

数论素数的判定与筛法

模板素数筛法

筛法求素数的几个模板

代码模板——素数筛法

素数专题——素数筛法