線性篩的同時得到歐拉函數 (KuangBin板子)

 

 

線性篩的思想:每個被篩的數是通過它最小的質因子所篩去的。

這種思想保證了每個數只會被篩一次,從而達到線性。並且,這個思想實現起來非常巧妙(見代碼註釋)!

 

因爲線性篩的操作中用到了倍數的關係去實現,因此歐拉函數可以順便也計算出來,根據完全積性函數的性質還有數學推算,直接一條語句就算出來了。

 

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<math.h>
 5 #include<algorithm>
 6 #include<queue>
 7 #include<stack>
 8 #include<deque>
 9 #include<iostream>
10 using namespace std;
11 typedef long long  LL;
12 const int N = 100009;
13 
14 int check[N];
15 int prime[N];
16 int phi[N];
17 int cnt;
18 
19 
20 void is_prime(int n)
21 {
22     int i,p,j;
23     cnt=0;
24     phi[1]=1;
25     for(i=2;i<=n;i++)
26     {
27         if(!check[i])
28         {
29             prime[cnt++]=i;
30             phi[i]=i-1;
31         }
32         for(j=0;j<cnt;j++)
33         {
34             if(i*prime[j]>n)
35                 break;
36             check[i*prime[j]]=1;
37 
38             if(i%prime[j]==0)
39             {
40                 /*因爲 i%prime[j]==0 ,所以i 是 prime[j] 的倍數, i 就可以看成 prime[j]*k , 這樣
41                 就相當於篩去 prime[i]的k*prime[j+1] 倍,但是這個數不應當現在被處理,而是在 i==prime[j+1]*k時被篩掉 */
42 
43                 phi[i*prime[j]]=phi[i]*prime[j];    // 因爲prime[j] 是質數,所以prime[j] 不可再分解,因此 i*prime[j] 的分解形式爲 i 的分解形式再乘以 prime[j],
44                                                     // 根據 歐拉函數的定義,i*prime[j] 的歐拉函數爲 prime[j]*phi[i] ;
45                 break;
46             }
47             else
48                 phi[i*prime[j]]=phi[i]*(prime[j]-1);    //當 i 不是    prime[j] 的倍數的時候,歐拉函數位完全積性函數,滿足積性函數的特點
49         }
50     }
51 }
52 int main()
53 {
54     int i,p,j,n;
55     is_prime(100);
56     for(i=0;i<cnt;i++)
57     {
58         printf("%d ",prime[i]);
59     }
60     return 0;
61 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章