首页 > 其他分享 >欧拉定理及欧拉函数

欧拉定理及欧拉函数

时间:2024-12-04 13:43:39浏览次数:4  
标签:phi 函数 int 定理 varphi cdot prod 欧拉

更新日志 2024/12/04:添加线性筛法求欧拉函数完整证明以及模板

前言

一些话以及借鉴感谢[点击展开]

从这里开始重写(学)数论,从头开始,就不搬运原博客了。

欧拉函数部分借鉴这一篇博客,线性筛算法证明借鉴这一篇博客,在此一并感谢。

线性筛法模板改自原博客,感觉当初的证明很神秘,使用了容斥原理,也可以参考,这里就不写了,意义不大。

欧拉函数

概念

符号为 \(\varphi\),英文 \(\rm phi\)。

\(\varphi(n)\) 表示所有小于等于 \(n\) 的数中,与 \(n\) 互质的数的个数。例如,\(\varphi(1)=1,\varphi(2)=1,\varphi(3)=2\dots\)

欧拉函数是积性函数,\(\forall(a,b)\in\{(a,b)|\gcd(a,b)=1\},\varphi(a\cdot b)=\varphi(a)\cdot\varphi(b)\)

基本公式与结论

结论一

\(\forall p\in \{素数\},\varphi(p)=p-1\),这是显然的,任意小于 \(p\) 的数均与其互质,因为 \(p\) 是质数。

结论二

\(\forall i\in N^*\),设其所有质因数为 \(p_1,p_2,\dots,p_s\),则

\[\varphi(i)=i\cdot\prod_{j=1}^{s}\frac{p_j-1}{p_j} \]

这就不是很显然了,所以我们推导一下:

引理1:若 \(p\) 为质数,\(k\) 为正整数,则 \(\varphi(p^k)=p^k-p^{k-1}\)

证明不难,考虑不与 \(p^k\) 互质且小于等于 \(p^k\) 的数 \(n\),那么必然满足 \(p|n\),那么在 \([1,p^k]\) 范围内,这样的 \(n\) 有 \(\frac{p^k}{p}=p^{k-1}\) 个。

因此,\(\varphi(p^k)=p^k-p^{k-1}\)。

引理2:根据唯一分解定理将 \(n\) 分解为 \(\prod\limits_{i=1}^{s}p_i^{k_i}\),则 \(\varphi(n)=n\cdot\prod\limits_{i=1}^{s}\frac{p_i-1}{p_i}\)。

我们只需要推导一下公式即可:

\[\begin{aligned} \varphi(i) &=\varphi(\prod_{i=1}^s p_i^{k_i}) \\ &= \prod_{i=1}^s \varphi(p_i^{k_i}) \\ &= \prod_{i=1}^s (p_i^{k_i}-p_i^{k_i-1}) \\ &= \prod_{i=1}^s p_i^{k_i}\cdot\prod_{i=1}^s (1-\frac{1}{p_i}) \\ &= n\cdot \prod_{i=1}^s\frac{p_i-1}{p_i} \end{aligned} \]

根据引理2,我们可以做到 \(O(\sqrt n)\) 求 \(\varphi(n)\)。

基础版模板

int solve(int n){
    ll res=n;
    for(int i=2;i<=n/i;i++){
        if(n%i)continue;
        res/=i;res*=i-1;
        while(n%i==0)n/=i;
    }
    if(n>1)res/=n,res*=n-1;
    return res;
}

线性筛求欧拉函数

理论

这是最常见的一种欧拉函数求法。

首先我们可以得到:

\[\varphi(n\cdot p)=\begin{cases}\varphi(n)\cdot(p-1) &\mathrm{if}\gcd(n,p)=1 \\ \varphi(n)\cdot p &\mathrm{if} \gcd(n,q)\ne 1\end{cases} \]

上一种很简单,\(\varphi(p)=p-1\)。

至于下一种,不难发现 \(p|n\),那么 \(p\) 为 \(n\) 的一个质因数,因此 \(n p\) 与 \(n\) 的质因数种类并无差别,根据引理2,整个公式后面的部分都是不变的,只是最前面的 \(n\) 变成了 \(n p\),所以 \(\varphi(n p)=\varphi(n)\cdot p\)。

最后,因为线性筛的原理是用每个数的最小质因数筛掉它,所以就可以使每一个数的 \(\varphi\) 都只被计算一次。

证毕。

线性筛法模板

为了好看简洁,使用宏定义,更通用版本在第二个代码块内。

int cnt;
int prime[N];
bool st[N];
int phi[N];
void euler(int n){
    phi[1]=1;
    #define p prime[j]
    rep(i,2,n){
        if(!st[i]){
            prime[++cnt]=i;
            phi[i]=i-1;
        }
        for(int j=1;p<=n/i;j++){
            st[i*p]=true;
            if(i%p==0){
                phi[i*p]=phi[i]*p;
                break;
            }else phi[i*p]=phi[i]*(p-1);
        }
    }
}

无宏定义版本:

int cnt;
int prime[N];
bool st[N];
int phi[N];
void euler(int n){
    phi[1]=1;
    rep(i,2,n){
        if(!st[i]){
            prime[++cnt]=i;
            phi[i]=i-1;
        }
        for(int j=1;prime[j]<=n/i;j++){
            st[i*prime[j]]=true;
            if(i%prime[j]==0){
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }else phi[i*prime[j]]=phi[i]*(prime[j]-1);
        }
    }
}

标签:phi,函数,int,定理,varphi,cdot,prod,欧拉
From: https://www.cnblogs.com/HarlemBlog/p/18583949

相关文章

  • 初识C语言|笑谈函数指针与数组
    C语言函数指针和函数指针数组:代码世界的“神秘宝藏” 家人们,今天咱来唠唠C语言里超“哇塞”的函数指针和函数指针数组,这俩可堪称代码宇宙中的“神秘宝藏”,一旦掌握,那编程水平直接“起飞”,在代码江湖中“大杀四方”都不是事儿。 先说说函数指针,这玩意儿就像是给函数定......
  • 小毕常用滴 激活函数
        前言:小毕总结了四个常用的激活函数相信大家肯定都知道也用烂了都, 那就再帮大家复习一下吧!我也借着写文章这个机会回忆回忆几个常用的激活函数 嘻嘻   简易网络结构:SoftMax激活函数    概念:SoftMax一般运用在 多分类需求的输出......
  • MySQL 常用的日期函数
    两个日期相减:TIMESTAMPDIFF函数语法:TIMESTAMPDIFF(unit,begin,end)说明:TIMESTAMPDIFF函数返回end-begin的结果,其中begin和end是DATE或DATETIME表达式。unit参数是确定end-begin的结果的单位,表示为整数。以下是有效单位:取值含义MICROSECOND毫秒SECOND......
  • CSS 函数
    目录一、介绍二、var()函数1.语法2.声明3.使用4.回退值5.作用域1)全局2)局部6.优先级7.var函数配合calc()使用三、calc()函数1.作为属性值使用:2.calc()常用的基本运算:3.calc()与自定义属性混合使用4.calc()函数与attr()函数无法混合使用四、attr()函数五、其他函数1.min()函......
  • 欧拉路/欧拉回路 学习笔记【未完工】
    判定有向图首先这张图将所有的有向边转为无向边之后图连通。反例:其次,我们知道当且仅当所有点的入度和出度都相等,才会有欧拉回路。因为一个点进去之后一定会出来,所以入度一定等于出度。同理,我们也可以知道入度和出度差\(1\)时,才会有欧拉路。因为不要从起点走回起点,所以起点......
  • 《Boundary-induced and Scene-aggregated Network for Monocular Depth Prediction》
    Boundary-inducedandScene-aggregatedNetworkforMonocularDepthPrediction这篇论文主要是做有监督深度估计,这里重点看了一下他的创新点和损失函数创新点针对创新点,主要遇到的一个问题是深度估计边缘不清晰,边缘处深度估计不准确BUBF自底向上的边界融合模块每一层编码器......
  • shell编程作业,获取ipv4的地址+crontab定时任务+无限重启Linux+⽤Shell写⼀个计算器+⽤
    公众号:泷羽Sec-尘宇安全声明!学习视频来自B站up主泷羽sec有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关,切勿触碰法律底线,否则后果自负!!!!有兴趣的小伙伴可以点击......
  • 高性能计算-NEON-intrinsic函数
    1.对寄存器数据重排/*两个向量,每两个通道一组,第一个向量每组的后一个元素与第二个向量每组的第一个元素一次彼此交换*/#include<stdio.h>#include<arm_neon.h>voidmain(){intarrc[8]={0};intarrd[4]={0};intarre[4]={0};//1234//5......
  • python函数参数传递是否比C语言更高效?——ChatGPT的回答
    Python的函数参数传递并不一定比C语言更高效,两者在效率上的差异主要取决于底层实现和具体的使用场景。以下是详细的比较:C语言参数传递效率按值传递(PassbyValue)是C中的默认方式:函数调用时,实参的值被复制到形参。这意味着函数内部的修改不会影响外部变量。C使用编译......
  • Python 奇怪的设定:为什么没有 main 函数?
    大家好!上次我们简单聊了Python为什么没有main函数,今天我们来更详细地探讨一下,并用代码进行佐证,帮助大家彻底理解Python的代码执行机制!1.Python代码如何执行?Python是一种解释型语言,这意味着代码不需要编译成机器码,而是由Python解释器逐行读取并执行。2. `__na......