• 欧拉函数一些定理的证明


    参考书籍:《ACM-ICPC程序设计系列--数论及应用》

    欧拉函数φ(n)指不超过n且与n互质的正整数的个数,其中n是一个正整数。

    欧拉函数的性质:它在整数n上的值等于对n进行素因子分解后,所有的素数上的欧拉函数之积。

    定义:

      1.定义在所有正整数上的函数称为算数函数

        2.算法函数f如果满足对任意两个互质的正整数n和m,均有f(mn)=f(n)f(m),就称为积性函数。如果对任意的两个正整数n和m,均有f(mn)=f(m)f(n),就称为完全积性函数。

    (欧拉函数就是一个积性函数证明:http://www.cnblogs.com/372465774y/archive/2012/10/16/2726282.html

    定理:

      1.如果f是一个积性函数,对任意正整数n有素数幂分解n=p1a1  * p2a2  * .... *psas,那么f(n)=f(p1a1)*f(p2a2)*...*f(psas)。

        2.如果p是素数,那么φ(n)=p-1;反之如果p是一个正整数且满足φ(p)=p-1,那么p是素数。  

        3.设p是素数,a是一个正整数,那么φ(pa)=pa-pa-1

    证明:比pa小的数有pa-1个,因为pa只有一个素因子p,其中与p不互质的有pa-1-1(分别是1*p,2*p,3*p....(pa-1-1)*p )

    所以φ(pa)=(pa-1)-(pa-1-1)=pa-pa-1  证毕。

        4.设n和m是互质的正整数,那么φ(nm)=φ(n)φ(m)  (因为欧拉函数是积性函数嘛,上面有证明)。

             5.设n=p1a1  * p2a2  * .... *pka为正整数n的素数幂分解,那么

            φ(n)=n * (1-1/p1)*(1-1/p2)*....*(1-1/pk)  (算法的核心)

    证明:由定理4可知φ(n)=φ(p1a1)*φ(p2a2)*.....*φ(pkak

      再由定理3得φ(n)=(p1a1-p1a1-1)*(p2a2-p2a2-1)*.....*(pkak-pkak-1

      提取因素得φ(n)=p1a1 (1-1/p1)*p2a2(1-1/p2)*pkak(1-1/pk

      所以φ(n)=n * (1-1/p1)*(1-1/p2)*....*(1-1/pk) 证毕。

    推论:当n为奇数时,有φ(2n)=φ(n);

    证明:设n=p1a1  * p2a2  * .... *pkak(假设p1是2)    则 φ(n)=n * (1-1/p1)*(1-1/p2)*....*(1-1/pk)

    那么2n=p1a1+1  * p2a2  * .... *pkak  即φ(2n)=(p1a1+1-p1a1)*(p2a2-p2a2-1)*.....*(pkak-pkak-1

                              =p1a1 (p1-1)*p2a2(1-1/p2)*pkak(1-1/pk

                              =n * (p1-1)*(1-1/p2)*....*(1-1/pk)

                              =n *(1-1/p2)*....*(1-1/pk) 

    因为n为奇数所以没有2这个素因子,即a1=0. 所以φ(n)=n *(1-1/p2)*....*(1-1/pk)=φ(2n) 证毕。

             6.设n是一个大于2的正整数,那么φ(n)是偶数

    证明:因为φ(n)=(p1a1-p1a1-1)*(p2a2-p2a2-1)*.....*(pkak-pkak-1) 

    情况一:n有2这个素因子时,piai-piai-1(令pi=2)一定是偶数(偶数减偶数嘛)φ(n)是一个偶数的倍数当然是偶数了。

    情况二 : n没有2这个素因子,一定存在一个奇素因子,piai-piai-1为偶数(因为 p^a与p^(a-1) 均为奇数)

        7.∑d|nφ(d)=n  (即n的因子的欧拉函数值之和为n)

    证明:

    情况一:n=1时显然成立

    情况二:n≠1时,

    定理基本介绍完了,我们来看代码:

    如果根据定理5直接实现:

    int phi(int n)
    {
        int rea=n;
        for(int i=2;i<=n;i++)
        {
            if(n%i==0)//找到素因子 
            {
                rea=rea/i*(i-1);
                while(n%i==0)//把该素因子全部约掉 
                    n/=i;    
            }
        }
        return rea;
    }

    时间复杂度为O(n),还可以优化降到O(√n),因为任何一个合数都至少有一个不大于√n的素因子,所以只需要遍历√n即可

    int phi(int n)
    {
        int rea=n;
        for(int i=2;i*i<=n;i++)//变化的地方 
        {
            if(n%i==0)
            {
                rea=rea/i*(i-1);
                while(n%i==0)
                    n/=i;    
            }
        }
        if(n>1)//有可能有一个大于√n素因子 
            rea=rea/n*(n-1);
        return rea;
    }

    如果最后n>1,为什么一定是一个大于√n的素因子。简单说下,因为不可能是两个及以上素因子的乘积。因为倒数第二个素因子一定小于√n。

  • 相关阅读:
    iptables
    vsftpd安装
    完整java开发中JDBC连接数据库代码和步骤
    java中使用队列:java.util.Queue
    程序中遇到重点问题
    在JSP页面中用select下拉列表来显示List列表的方式
    java.lang.String cannot be cast to [Ljava.lang.Object;
    java虚拟机的内存设置
    网络协议都有哪些
    使用java技术将Excel表格内容导入mysql数据库
  • 原文地址:https://www.cnblogs.com/xiongtao/p/10686183.html
Copyright © 2020-2023  润新知