zoukankan      html  css  js  c++  java
  • 欧拉函数小结

    欧拉函数:

    φ(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 }
    欧拉函数线性筛和莫比乌斯函数线性筛
  • 相关阅读:
    【SICP练习】150 练习4.6
    windows已安装solr
    ps快速删除圆角图片旁白的白色区域方法
    junit学习笔记(二):hamcrest和TestSuit
    取球游戏
    【Linux操作系统分析】设备驱动处理流程
    POJ Secret Milking Machine 【网络流+二分】
    oracle 10 g 需要启动的2个服务
    jQuery也能舞出绚丽的界面(完结篇)
    HDU 2665(Kth number-区间第k大[内存限制+重数])
  • 原文地址:https://www.cnblogs.com/Milkor/p/4471495.html
Copyright © 2011-2022 走看看