wenbao與篩法素數及判斷模板

weixin_30588675發表於2020-04-05
 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 }

 

 

 

只有不斷學習才能進步!

 

轉載於:https://www.cnblogs.com/wenbao/p/5733527.html

相關文章