博客
关于我
AcWing 874. 筛法求欧拉函数
阅读量:803 次
发布时间:2023-04-02

本文共 1434 字,大约阅读时间需要 4 分钟。

如何高效计算1到n的欧拉函数之和

欧拉函数φ(n)表示小于等于n且与n互质的正整数的个数。为了计算1到n中每个数的欧拉函数之和,我们可以使用线性筛法,这种方法的时间复杂度为O(n log log n),非常高效。

方法概述

  • 初始化数据结构

    • 使用一个布尔数组st来标记是否已经被处理的数。
    • 使用一个数组primes来存储所有质数。
  • 遍历每个数

    • 对于每个数i,从2到n:
      • 如果i未被标记,则i是质数,加入primes数组,并设置st[i] = true
      • 计算质数i的欧拉函数值phi[i] = i - 1
  • 处理质数的倍数

    • 对于每个质数p,处理p的倍数t:
      • 如果t/p已经被处理过,则phi[t] = phi[t/p] * p
      • 否则,phi[t] = phi[t/p] * (p - 1),并标记t为已处理。
  • 累加欧拉函数值

    • 遍历1到n,累加每个数的欧拉函数值,得到最终结果。
  • 代码实现

    #include 
    #include
    #include
    using namespace std;
    typedef long long LL;
    const int N = 1e6 + 7;
    int primes[N], cnt;
    bool st[N];
    LL get_eulers(int n) {
    st[1] = true;
    for (int i = 2; i <= n; ++i) {
    if (!st[i]) {
    primes[cnt++] = i;
    st[i] = true;
    phi[i] = i - 1;
    }
    for (int j = 0; primes[j] <= n / i; ++j) {
    int t = primes[j] * i;
    st[t] = true;
    if (i % primes[j] == 0) {
    phi[t] = phi[i] * primes[j];
    break;
    }
    phi[t] = phi[i] * (primes[j] - 1);
    }
    }
    LL res = 0;
    for (int i = 1; i <= n; ++i) {
    res += phi[i];
    }
    return res;
    }
    int main() {
    int n;
    cin >> n;
    cout << get_eulers(n) << endl;
    return 0;
    }

    代码解释

    • 初始化st数组用于标记已处理的数,primes数组存储质数,phi数组存储每个数的欧拉函数值。
    • 遍历质数:对于每个数i,若未被标记,则为质数,加入primes数组,并计算其欧拉函数值。
    • 处理倍数:对于每个质数p,处理其倍数t,根据t的质因数分解情况计算欧拉函数值。
    • 累加结果:遍历所有数,累加欧拉函数值,返回结果。

    这种方法高效且适用于大范围的n,能够快速计算1到n的欧拉函数之和。

    转载地址:http://gaefk.baihongyu.com/

    你可能感兴趣的文章
    OSG学习:几何体的操作(二)——交互事件、Delaunay三角网绘制
    查看>>
    OSG学习:几何对象的绘制(一)——四边形
    查看>>
    OSG学习:几何对象的绘制(三)——几何元素的存储和几何体的绘制方法
    查看>>
    OSG学习:几何对象的绘制(二)——简易房屋
    查看>>
    OSG学习:几何对象的绘制(四)——几何体的更新回调:旋转的线
    查看>>
    OSG学习:场景图形管理(一)——视图与相机
    查看>>
    OSG学习:场景图形管理(三)——多视图相机渲染
    查看>>
    OSG学习:场景图形管理(二)——单窗口多相机渲染
    查看>>
    OSG学习:场景图形管理(四)——多视图多窗口渲染
    查看>>
    OSG学习:新建C++/CLI工程并读取模型(C++/CLI)——根据OSG官方示例代码初步理解其方法
    查看>>
    Sql 随机更新一条数据返回更新数据的ID编号
    查看>>
    OSG学习:空间变换节点和开关节点示例
    查看>>
    OSG学习:纹理映射(一)——多重纹理映射
    查看>>
    OSG学习:纹理映射(七)——聚光灯
    查看>>
    OSG学习:纹理映射(三)——立方图纹理映射
    查看>>
    OSG学习:纹理映射(二)——一维/二维/简单立方图纹理映射
    查看>>
    OSG学习:纹理映射(五)——计算纹理坐标
    查看>>
    OSG学习:纹理映射(六)——灯光
    查看>>
    OSG学习:纹理映射(四)——三维纹理映射
    查看>>
    OSG:从源码看Viewer::run() 一
    查看>>