• 算法模板-欧拉函数


    欧拉函数:给定一个正整数n,在小于等于n的数中,与n互质的数的个数。

    关于欧拉函数,有以下几个规律:

      1.当n为质数时,euler(n)=n-1.

      2.当p与q互质时,euler(p*q)=euler(p)*euler(q).

      3.当n等于p^k时,p为质数,euler(n)=p^k-p^(k-1).

    对于任意的n,有n=p1^m1*p2^m2*p3^m3……*pk^mk; p1……pk为质数,所以p1^m1……pk^mk都互质

    所以euler(n)=euler(p1^m1)*euler(p2^m2)……*euler(pk^mk)

    由于规律3,euler(p^k)=(p-1)*p^(k-1)

    推理可得:euler(n)=n*(1-1/p1)*(1-1/p2)……*(1-1/pk)

    算法实现:利用质因数分解,分解出质因数组合,套用公式即可。

    int euler(int n){
        int res=n;
        for(int i=2;i<n;i++){
            if(n%i==0){
                res=res/i*(i-1);
                while(n%i==0)n/=i;
            }
        }
        if(n!=1)res=res/n*(n-1);
        return res;
    } 

    如何求解1到n里的每个数的欧拉函数,显然对每个数都跑一遍欧拉函数时非常慢的。

    我们可以利用euler(p*q)=euler(p)*euler(q),通过前面已经计算出来的值,推导后面的值。

    可以使用线性筛/欧拉筛O(n),在计算n以内的质数的同时,计算n以内的欧拉函数。

    const int maxn=100009;
    int phi[maxn+1];                //phi[i]表示i的欧拉函数 
    int prime[maxn+1];                //prime[0]用来储存素数个数 
    void getPrime()
    {
        memset(prime,0,sizeof(prime));
        for(int i=2;i<=maxn;i++){
            if(!prime[i])prime[++prime[0]]=i,phi[i]=i-1;
            for(int j=1;j<=prime[0]&&prime[j]*i<=maxn;j++){
                prime[prime[j]*i]=1;
                if(i%prime[j]==0){
                    phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
                phi[i*prime[j]]=phi[i]*phi[prime[j]];
            }
        }
    }
  • 相关阅读:
    github用起来-pycharm中玩好github
    docker使用阿里云镜像报错
    林子大了什么鸟都有
    CentOS7部署docker
    虚拟机无法上网问题
    Centos7安装图形化界面
    分享一款非常棒的数据库文档生成工具,可导出md、excel等格式
    Java常见知识积累
    MySQL必知必会详细总结
    你真的会学习吗?从结构化思维说起
  • 原文地址:https://www.cnblogs.com/xinwang-coding/p/12724309.html
Copyright © 2020-2023  润新知