• 欧拉函数


    学习链接:https://baike.baidu.com/item/%E6%AC%A7%E6%8B%89%E5%87%BD%E6%95%B0/1944850?fr=aladdin

    在百度百科上面学了欧拉函数:

    欧拉函数

     编辑 讨论
    数论,对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目(φ(1)=1)。此函数以其首名研究者欧拉命名(Euler's totient function),它又称为Euler's totient function、φ函数、欧拉商数等。 例如φ(8)=4,因为1,3,5,7均和8互质。 从欧拉函数引伸出来在环论方面的事实和拉格朗日定理构成了欧拉定理的证明。
     
    中文名
    欧拉函数
    外文名
    Euler's totient function
    定    义
    小于n的数中与n互质的数的数目
    发现人
    欧拉(Euler)

     

    函数内容

    编辑
    通式:
     
    其中p1, p2……pn为x的所有质因数,x是不为0的整数。
    φ(1)=1(和1互质的数(小于等于1)就是1本身)。
    注意:每种质因数只一个。 比如12=2*2*3那么φ(12)=φ(4*3)=φ(2^2*3^1)=(2^2-2^1)*(3^1-3^0)=4
    若n是质数p的k次幂,
      
    ,因为除了p的倍数外,其他数都跟n互质。
    设n为正整数,以 φ(n)表示不超过n且与n互素的正整数的个数,称为n的欧拉函数值
    φ:N→N,n→φ(n)称为欧拉函数。
    欧拉函数是积性函数——若m,n互质,
     
    特殊性质:当n为奇质数时,
      
    , 证明与上述类似。
    若n为质数则
     
     
    下面说一种欧拉筛,用于求解区间内所有的数的欧拉函数:
    /**
    有三条特性
    若a为质数  phi[a]=a-1
    若a为质数,b%a==0   phi[a*b]=phi[b]*a;
    若a b 互质  phi[a*b]=phi[a]*phi[b](当a为质数  如果b%a!=0)
    
    */
    #include<iostream>
    using namespace std;
    const int maxn=1e5+50;
    int phi[maxn],prime[maxn],p[maxn];//phi[i]代表i的欧拉函数值  prime[i]=0代表是素数 1代表不是素数   p存储素数
    void make()
    {
        phi[1]=1;//特例 
        int num=0;
        for(int i=2;i<=maxn;i++)
        {
            if(!prime[i])//是素数
            {
                p[num++]=i;//
                phi[i]=i-1;//素数的欧拉函数值就是它的值减1
            }
            for(int j=0;j<num&&p[j]*i<maxn;j++)//用当前已经得到的素数筛去p[j]*i
            {
                prime[p[j]*i]=1;//可以确定p[j]*i不是质数
                if(i%p[j]==0)//第二条特性
                {
                    phi[p[j]*i]=phi[i]*p[j];
                    break;//欧拉筛的核心语句  保证每个数只会被自己最小的质因子筛掉一次
                }
                else phi[p[j]*i]=phi[i]*phi[p[j]];
            }
        }
        return ;
    }
    
    int main()
    {
        make();
    //    for(int i=1;i<=100;i++) cout<<phi[i]<<" ";
    
        return 0;
    }

    下面看一下单个值的欧拉值的求法:

    #include<iostream>
    #include<cmath>
    using namespace std;
    int eular(int n)
    {
        int res=n,m=n;
        for(int i=2;i<=sqrt(m);i++)
        {
            if(m%i==0)
            res=res/i*(i-1);
            while(m%i==0)
            m=m/i;
        }
        if(m>1)
        res=res/m*(m-1);
        return res;
    }
    int main()
    {
        int n;
        cin>>n;
        cout<<eular(n)<<endl;
        return 0;
    }
    当初的梦想实现了吗,事到如今只好放弃吗~
  • 相关阅读:
    性能分析一:查看程序占用系统的内存 .
    Winform中ToolTip的用法
    30岁的程序员
    序列化
    CMD中可执行的结束进程命令
    数据库设计规范与技巧
    判断字符串编码思路
    字符串加密思路
    在同一个页面施用多个不同的jQuery版本而不冲突的方法
    mysql 数据库设计
  • 原文地址:https://www.cnblogs.com/caijiaming/p/10638586.html
Copyright © 2020-2023  润新知