zoukankan      html  css  js  c++  java
  • 突然想写一篇有关欧拉函数的博客

    关于欧拉函数:

    定义:

    φ(n)表示1~n中与n互质的数的个数;

    求法:

    已知n的标准分解式为:

    (哦对了,这里所有的因子都是质因子)

    ​那么

    然后求欧拉函数的两种方法:

    1.按照定义暴力求解:

    int phi(int n){
        int ret=n;
        for(int i=2;i*i<=n;i++){
            if(n%i==0){
                ret-=ret/i;
                while(n%i==0) n/=i;
            }
        }
        if(n>1) ret-=ret/n;
        return ret;
    }

    解释一下:

    对于欧拉函数φ来说,我们每*(1-1/pn),就相当于在原数的基础上减掉原数*1/pn(这里的原数并不是指n,而是指n*某些数之后的数),假设原数为ret,那么我们将ret*(1-1/pz)的值就相当于ret-ret*1/pz,由此我们得出了ret-=ret/i;然后将n中的所有i统统除掉,防止出现再算一次的可凉(就是很凉)情况。最后,如果n>1,说明我们还有一个因子没有枚举到,此时n就是当前因子,用上方式子再减一下就好了;

    2.欧拉筛时顺带着求出来了???

    然后欧拉筛的话,可以求到的值比较小,如果单纯求φ的话,不如用定义呢

    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    #include<ctime>
    
    using namespace std;
    
    int n,cnt,maxx;
    int prime[10000010],phi[10000010];
    bool not_[10000010];
    
    void shai(){
        for(int i=2;i*i<=100000000;i++){
            if(!not_[i]) {
                prime[++cnt]=i;
                phi[i]=i-1;
            }
            for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
                not_[i*prime[j]]=1;
                if(i%prime[j]==0) {
                    phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
                else phi[i*prime[j]]=phi[i]*phi[prime[j]];
            }
        }
    }
    
    int main(){
        freopen("data.in","r",stdin);
        freopen("data.ans","w",stdout);
        cin>>n;
        shai();
        printf("%d",phi[n]);
    }

    end-

  • 相关阅读:
    用户控件被添加到容器的整个处理过程
    c#项目后期生成事件命令行常用命令
    Sass 系统知识
    非 root 用户
    Linux 系统版本查看
    Docker Swarm
    Docker Compose
    Linux RocketMQ双主双从,Centos7 RocketMQ4集群(双主双从)
    Linux RocketMQ安装配置和使用,Centos7 RocketMQ4安装配置
    Springboot Logback日志使用,Springboot Logback详细配置和日志分割
  • 原文地址:https://www.cnblogs.com/zhuier-xquan/p/11241008.html
Copyright © 2011-2022 走看看