欧拉函数:
φ(n)表示1~n中和n互素的数目
要处理出欧拉函数。先证明φ(p)=p-1.(p为素数)
根据互素的概念。两个数的公约数只有1,那么这两个数互素。再根据素数的定义。公约数除了本身以外只有1的数为素数。所以得证φ(p) = p-1.
再证明欧拉函数为不完全积性函数。
φ(m1*m2) = φ(m1)*φ(m2) 其中 m1和m2互素。即gcd(m1,m2)=1.
证明过程在我另外一篇博文中。我觉得那种证明比较好。当然还有别的比较好的证明方法。
http://www.cnblogs.com/Milkor/p/4464515.html
思考一个这样的经典问题。知道一个函数是积性的(其实只要是在两个互素数中的积性)。
那么根据算术基本定理(任何一个数可以拆分成素数的乘积形式)
φ(m) = φ(p1^k1) * φ(p2^k2) * φ(p3^k3) *...
那么我们只要求出φ(p^k)就可以求出任意数的对应的欧拉函数的对应值。
1~p^k 一共有p^k个数。
其中是p的倍数为 <p,2p,3p...p^k> (最后那个数可以列不等式找出来)。个数为p^k/p = p^(k-1).
所以和p^k互素的数的个数为 p^k - p^(k-1).
那么根据上述。可得
以上便是欧拉公式的来源。
顺便根据我们上述的推论,我们再推导一下线性筛法欧拉函数中。
当i%j==0的时候。也就是j为i的因子的时候。
φ(i*j)=φ(i)*j.这个结论吧。
证明过程:
1 #include<stdio.h> 2 #include<string.h> 3 #define N 100 4 5 int primeE[N+5]; 6 int primeM[N+5]; 7 int numE; 8 int numM; 9 bool mark[N+5]; 10 int euler[N+5]; 11 int mobius[N+5]; 12 13 void Euler() 14 { 15 int i,j; 16 numE = 0; 17 memset(mark,0,sizeof(mark)); 18 euler[1] = 0; 19 for(i=2;i<=N;i++) 20 { 21 if(!mark[i]) 22 { 23 primeE[numE++] = i; 24 euler[i]=i-1; 25 } 26 for(j=0;j<numE;j++) 27 { 28 if(i*primeE[j]>N){break;} 29 mark[i*primeE[j]] = 1; 30 if(i%primeE[j]==0) 31 { 32 euler[i*primeE[j]] = euler[i]*primeE[j]; 33 break; 34 /* 35 原理:例如要构造24 36 3*8 = 24 = 2*12 37 8中有2的因子。8拆分成2*i. 把i给3 一定可以构造出最小的质因子。 38 把一个合数当做最小质因子*另外一个数 来处理。 39 */ 40 } 41 else 42 { 43 euler[i*primeE[j]] = euler[i]*euler[primeE[j]]; 44 } 45 } 46 } 47 } 48 void Mobius() 49 { 50 int i,j; 51 numM = 0; 52 memset(mark,0,sizeof(mark)); 53 mobius[1] = 1; 54 for(i=2;i<=N;i++) 55 { 56 if(!mark[i]) 57 { 58 primeM[numM++] = i; 59 mobius[i] = -1; 60 } 61 for(j=0;j<numM;j++) 62 { 63 if(i*primeM[j]>N){break;} 64 mark[i*primeM[j]] = 1; 65 if(i%primeM[j]==0) 66 { 67 mobius[i*primeM[j]] = 0; 68 break; 69 } 70 else 71 { 72 mobius[i*primeM[j]] = -mobius[i]; 73 } 74 } 75 } 76 } 77 int main() 78 { 79 Euler(); 80 Mobius(); 81 int i; 82 for(i=0;i<numE;i++) 83 { 84 printf("%d ",primeE[i]); 85 } 86 printf(" "); 87 for(i=0;i<numM;i++) 88 { 89 printf("%d ",primeM[i]); 90 } 91 printf(" "); 92 for(i=1;i<=N;i++) 93 { 94 printf("%d=%d ",i,euler[i]); 95 } 96 printf(" "); 97 for(i=1;i<=N;i++) 98 { 99 printf("%d=%d ",i,mobius[i]); 100 } 101 }