AcWing 874. 筛法求欧拉函数(欧拉函数)

Posted MangataTS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AcWing 874. 筛法求欧拉函数(欧拉函数)相关的知识,希望对你有一定的参考价值。

题目链接

https://www.acwing.com/problem/content/876/

思路

对于一个数x如果是质数,那么它的欧拉函数就为 x − 1 x-1 x1,对于其他合数我们可以将其拆成最小的质数的积,那么这个过程我们就可以通过欧拉筛法来计算欧拉函数值,现在我们还有两种情况需要讨论

  • 如果i能整除prime[j]说明prime[j]是i的一个质因子,那么对于i*prime[j]来说其实就是 p h i [ i ] ∗ p r i m e [ j ] phi[i] * prime[j] phi[i]prime[j]
  • 如果i不能整除prime[j]说明prime[j]不是i的质因子,那么我们最后需要乘上一个 1 − 1 p r i m e [ j ] 1-\\frac1prime[j] 1prime[j]1所以也就是 p h i [ i ] ∗ ( p r i m e [ j ] − 1 ) phi[i] * (prime[j] - 1) phi[i](prime[j]1)

代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long

const int N = 1e6+10;

ll phi[N],prime[N];
bool vis[N];


ll cal_oular(int n)
    phi[1] = 1;
    for(int i = 2;i <= n; ++i)
        if(!vis[i]) prime[++prime[0]] = i,phi[i] = i - 1;
        for(int j = 1;i * prime[j] <= n && j <= prime[0]; ++j) 
            vis[i * prime[j]] = true;
            if(i % prime[j] == 0)
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            
            phi[i * prime[j]] = phi[i] * (prime[j] - 1);
        
    
    ll ans = 0;
    for(int i = 1;i <= n; ++i) ans += phi[i];
    return ans;


int main()

    ll n;
    scanf("%lld",&n);
    printf("%lld\\n",cal_oular(n));
    
    
    return 0;

以上是关于AcWing 874. 筛法求欧拉函数(欧拉函数)的主要内容,如果未能解决你的问题,请参考以下文章

筛法求欧拉函数(poj2478

初等数论-Base-1(筛法求素数,欧拉函数,欧几里得算法)

欧拉线性筛 和 欧拉函数的求值

欧拉函数及费马定理

欧拉筛法求素数模版

欧拉筛法求素数