线性筛的同时得到欧拉函数 (参考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 }
原文地址:https://www.cnblogs.com/daybreaking/p/9826855.html