当前位置: 首页 > news >正文

欧拉函数学习笔记

欧拉函数学习笔记

1.定义

先讲一下欧拉函数的定义:欧拉函数 \(\phi(n)\) 定义为不超过 \(n\) 且与 \(n\) 互质的正整数的个数。

\(\phi(n)=\sum_{i=1}^{n}[\gcd(i,n)=1]\)

例子

  • n = 8:小于 \(n\) 的正整数是 [1, 2, 3, 4, 5, 6, 7, 8]
    • 82 有共同因数 2,不满足。
    • 84 有共同因数 4,不满足。
    • 81, 3, 5, 7 的最大公约数都是 1,所以它们满足。
    • 所以 \(\phi(8)=4\)

2.理通解式

通解式 φ(n) = n * (1 - 1/p₁) * (1 - 1/p₂) * ...这个公式看起来吓人,但它其实就是一个高效的“排除法”

想象一下
你要从 1n 中找出所有和 n 互质的数。最笨的办法是一个个检查。但我们可以聪明一点,直接把肯定不是符合的数踢出去。

步骤

  1. 找出 n 的所有质因数。比如 n = 12,它的质因数是 23
  2. 踢掉所有 2 的倍数:在 1-12 中,2 的倍数有 6 个(12 * 1/2 = 6)。踢掉后,剩下 12 * (1 - 1/2) = 6 个数。
  3. 踢掉所有 3 的倍数:在剩下的 6 个人里,有多少是 3 的倍数呢?因为 23 互质,所以分布是均匀的。所以要再踢掉剩下个数的 1/3。最终剩下 12 * (1 - 1/2) * (1 - 1/3) = 4 个人。

4 个人就是 [1, 5, 7, 11],正好是 φ(12) 的值。这个公式就是一个高效的“筛子”,把所有和 n 有共同质因数的数都筛掉了。

三、理解两个核心性质

性质1:如果 p 是质数,那么 φ(p) = p - 1

  • 简单理解:质数 p 的"契合度"非常高。因为它除了 1 和它自己,没有其他因数。所以从 1p-1所有数都和它满足!只有它自己(p)和它不互质(gcd(p, p) = p)。
  • 例子p = 7[1, 2, 3, 4, 5, 6] 全部和它满足,所以 φ(7) = 6

性质2:欧拉函数是“积性函数”(当 mn 互质时,φ(m*n) = φ(m) * φ(n)

这是最难直观理解的一点,但可以用一个二维网格来想象。

  • 想象一个 mn 列的网格,总共有 m * n 个格子。我们可以用坐标 (i, j) 来表示每个格子,其中 1 ≤ i ≤ m, 1 ≤ j ≤ n
  • 问题:有多少个格子 (i, j) 满足 gcd(i, j) = 1?这其实就等价于 φ(m*n)(在特定条件下)。
  • 关键洞察:因为 mn 互质,根据中国剩余定理gcd(i, j) = 1 当且仅当 gcd(i, m) = 1 并且 gcd(j, n) = 1
  • 所以:满足条件的格子数 = (i 的合法选择数) * (j 的合法选择数) = φ(m) * φ(n)

虽然这个解释用到了一点高级概念,但你可以把它理解为:当两个数 mn 没有任何共同的“麻烦”(互质)时,它们的“契合度”大小可以直接相乘,不会互相干扰

例题

接下来讲一个例题:P2158仪仗队

1. 初始化与特判

p[1] = 1; // 1要特判
  • 解释:根据欧拉函数的定义,φ(1) = 1。因为小于等于1且与1互质的正整数只有1本身。这是一个基础的边界条件,需要单独处理。

2. 主循环:遍历每个数 i

for(re int i=2; i<=n; ++i)
  • 解释:从 2 开始遍历到 n2 是最小的质数。

3. 判断 i 是否为质数

if(!b[i]) // 这代表i是质数
{prime[++num] = i;p[i] = i - 1;
}
  • 变量说明
    • b[] 是一个布尔标记数组(通常初始化为 false)。b[i] == true 表示 i 是合数。
    • prime[] 数组用于存储找到的质数。
    • num 是已找到质数的计数器。
  • 逻辑
    • 如果 b[i]false,说明 i 没有被任何更小的质数筛掉,因此 i 本身是一个质数。
    • i 加入质数数组 prime
    • 关键:对于任意质数 pφ(p) = p - 1。因为从 1p-1 的所有整数都与 p 互质。

4. 筛选合数并计算其欧拉函数

这是线性筛的核心部分,通过已知的质数 prime[j] 去筛掉 i * prime[j] 这个合数,并同时计算 p[i * prime[j]]

for(re int j=1; j<=num && prime[j]*i<=n; ++j)
{b[i * prime[j]] = 1; // 先把这个合数标记掉...
}
  • 解释:内层循环遍历所有已找到的质数 prime[j],尝试用 prime[j] 去乘 i,生成一个新的合数 i * prime[j],并将其标记为合数。

接下来是计算欧拉函数值的关键分支,它基于 iprime[j] 的关系,利用了欧拉函数的两个核心性质。

情况一:prime[j]i 的质因子 (i % prime[j] == 0)

if (i % prime[j] == 0)
{p[i * prime[j]] = p[i] * prime[j];break;
}
  • 数学原理:假设 i 已经包含了质因子 prime[j],即 i = prime[j]^k * m(其中 mprime[j] 互质)。那么 i * prime[j] = prime[j]^(k+1) * m
    根据欧拉函数的通式:
    • φ(i) = i * (1 - 1/prime[j]) * ...... 代表 m 的其他质因子部分)
    • φ(i * prime[j]) = i * prime[j] * (1 - 1/prime[j]) * ... = prime[j] * φ(i)
  • 结论:当 prime[j] 整除 i 时,φ(i * prime[j]) = φ(i) * prime[j]
  • break 的作用:这是线性筛保证线性时间复杂度的核心。因为 prime[j]i 的最小质因子(筛法的性质),所以 prime[j] 也是 i * prime[j] 的最小质因子。为了确保每个合数只被其最小的质因子筛掉一次,我们在此处 break,不再用更大的质数去乘 i

情况二:prime[j]i 互质 (i % prime[j] != 0)

else
{p[i * prime[j]] = p[i] * p[prime[j]];
}
  • 数学原理:此时 iprime[j] 互质(因为 prime[j] 是质数且不能整除 i)。
  • 关键性质:欧拉函数是一个积性函数。这意味着,如果 gcd(a, b) = 1,那么 φ(a * b) = φ(a) * φ(b)
  • 结论:因为 gcd(i, prime[j]) = 1,所以 φ(i * prime[j]) = φ(i) * φ(prime[j])。而 φ(prime[j]) = prime[j] - 1,这个值在 prime[j] 被识别为质数时就已经计算并存储在 p[prime[j]] 中了。
http://www.hskmm.com/?act=detail&tid=16913

相关文章:

  • PDF论文文字公式提取,翻译与对照代码(自用)
  • Lambda表达式 - AlgosEng
  • ABAP 调用HTTP上传附件中文乱码
  • PDF入参以及模板对应签章图踩坑点 JAR版本为 iText5
  • 从 0 到 1 精通 SkyWalking:分布式系统的 “透视镜“ 技巧全解析
  • 系统调用brk 和 mmap 有什么不同?
  • 雷达系统杂波设计与仿真
  • 国标GB28181视频平台EasyCVR一体化加油站安防视频监控方案与实践
  • JavaScript 沙箱
  • PDF入参以及模板对应签章图踩坑点
  • 高性能PCIe 3.0软核,x1~x16,支持EP/RC,AXI4接口,内置DMA控制器,适用ASIC和FPGA
  • 使用git clone 批量下载huggingface模型文件
  • Python 换进安装GDAL
  • sync(同步本地文件到OSS)
  • MyBatisPlus 会默认设置 mybatis 的 scanPackages 为当前 BeanFactory 的 auto-configuration 的 base packages
  • 工程实践 使用本地包开发python项目
  • 详细介绍:Python + Flask + API Gateway + Lambda + EKS 实战
  • 日记4
  • P2042 [NOI2005] 维护数列 题解
  • 达梦数据库查询字段类型为Date 修改为DateTime
  • C++ new 操作符在操作系统层执行了什么操作?
  • [ABC422F-G] 题解
  • 别再靠 “关设备” 减碳!EMS 的 “预测性控能”,让企业满产也能达标双碳
  • LAMP 架构说明及部署实践 - 教程
  • MyEMS 深度解析:核心功能模块、数据流转逻辑与工业能源优化落地路径
  • kettle插件-国产数据库金仓插件,助力国产数据库腾飞
  • 制造业碳足迹追踪:开源能源管理系统如何助力企业实现“碳数据可视化”?
  • iframe安全盲区:支付信息窃取攻击的新温床 - 教程
  • 综合网表中有assign怎么办
  • 极限与导数