筛法求欧拉函数之和

题目描述

1n每个数欧拉函数之和

想法

  1. 如果i是质数
    φ(i)=i1

质数i只有1i两个因数,i不和i本身互质,因数只有一个1,所以互质的数就有i1

  1. 如果i不是质数
  1. i%j=0
    j是质数
    ji的一个质因子,所以φ(i)中已经包含了j

φ(j×i)=j×i×(11p1)×(11p2)××(11pk))
因为 φ(i)=i×(11p1)×(11p2)××(11pk)
将②代入①中得:
φ(j×i)=j×φ(i)

  1. i%j0
    j不是i的质因子,根据线性筛中的推导,jj×i的最小质因子

所以φ(j×i)=φ(i)×φ(j)
由1可得,如果j是质数:φ(j)=j1
φ(j×i)=φ(i)×(j1)

发现过程中有关质因数,想到线性筛
所以我们可以套用线性筛的板子

码来!

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1e6+10;

typedef long long LL;

int primes[N], idx; // 记录质数,idx是下标
int phi[N]; // 存储每个欧拉函数的值
bool st[N]; // 是否是质数

LL get_phi(int n)
{
    phi[1] = 1;
    
    for (int i = 2; i <= n; i ++ )
    {
        if(!st[i]) // 如果i是质数
        {
            primes[idx++] = i;
            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) // j是i的质因数的情况
            {
                phi[t] = phi[i] * primes[j];
                break;
            }
            // j不是i的质因数的情况
            phi[t] = phi[i] * (primes[j] - 1);
        }
    }
    
    LL res = 0; // 用longlong类型存储 —— 怕爆int

    for(int i = 1; i <= n; i++)
    {
        res += phi[i]; // 计算从1到n的欧拉函数之和
    }
    
    return res;
}

int main()
{
    int n;
    cin >> n;

    LL ans = get_phi(n);

    printf("%lld\n", ans);
    
    return 0;
}

欢迎大佬指出本蒟蒻的错误!

posted @   MoyouSayuki  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
:name :name
点击右上角即可分享
微信分享提示