欧拉函数——数学知识(c++)

定义:欧拉函数表示1-N中与N互质的数的个数;
给定一个数n,求在[1,n]这个范围内两两互质的数的个数
对于这个范围内的每一个数,我们只要找到不超过这个数且与这个数互质的数的个数就可以了
欧拉函数用希腊字母φ表示,φ(N)表示N的欧拉函数.
在这里插入图片描述

欧拉函数的简单性质

1.欧拉函数是积性函数(非完全);

积性函数:对于任意互质的整数a和b有性质f(ab)=f(a)f(b)的数论函数。

完全积性函数:对于任意整数a和b有性质f(ab)=f(a)f(b)的数论函数。

2.除了N=2,φ(N)都是偶数;

3.当N为奇数时,φ(2*N)=φ(N);

4.若N是质数p的k次幂,φ(N)=pk-p(k-1)=(p-1)p^(k-1) 因为除了p的倍数之外,其他数都与N互质;

5.当N是质数时,φ(N)=N-1;

若将N表示成质因子分解式
在这里插入图片描述
在这里插入图片描述
所以我们有
6.φ(N)=N*(1-1/P1)(1-1/P2)…*(1-1/Pn).

求n的欧拉值

首先, 欧拉函数是一个积性函数,当m,n互质时,φ(mn)=φ(m)∗φ(n)
根据唯一分解定理知 n=p1a1∗p2a2∗…∗pxax
因此 φ(n)=φ(p1a1)∗…∗φ(pxax)

对于任意一项 φ(psas)=psas−ps(as−1)
从定义出发 φ(psas)等于小于或等于psas的正整数中与psas互质的数的数目

从1到psas中共有psas个数字

其中与psas不互质的有ps,2ps,…,psas−1∗ps,共psas−1

扫描二维码关注公众号,回复: 13112118 查看本文章

所以 φ(psas) = psas - psas−1=psas∗(1−1/ps)
因此

φ(n)=φ(p1^a1^)∗…∗φ(px^ax^)
=(p1^a1^−p1^a1−1^)∗…∗(px^ax^−px^ax−1^)
=p1^a1^(11/p1)∗p2^a2^∗(11/p2)∗…∗px^ax^∗(11/px)
=p1^a1^∗p2^a2^∗…∗px^ax^(11/p1)∗(11/p2)∗…∗(11/px)
=n∗∏i=1x(11/pi)
作者:Sundae
链接:https://www.acwing.com/solution/content/8702/
来源:AcWing

经典例题

AcWing 873. 欧拉函数
给定n个正整数ai,请你求出每个数的欧拉函数。

欧拉函数的定义
1 ~ N 中与 N 互质的数的个数被称为欧拉函数,记为ϕ(N)。
若在算数基本定理中,N=p1a1p2a2…pmam,则:
ϕ(N) = N∗p1−1/p1 ∗ p2−1/p2 ∗ … ∗ pm−1/pm
输入格式
第一行包含整数n。

接下来n行,每行包含一个正整数ai。

输出格式
输出共n行,每行输出一个正整数ai的欧拉函数。

数据范围
1≤n≤100,
1≤ai≤2∗109
输入样例:

3
3
6
8

输出样例:

2
2
4
#include <iostream>

using namespace std;


int phi(int x)//一次性函数
{
    
    
    int res = x;
    for (int i = 2; i <= x / i; i ++ )
        if (x % i == 0)//只有x%i=0才会进
        {
    
    
            res = res / i * (i - 1);
            while (x % i == 0) x /= i;//一次性消除全部i
        }
    if (x > 1) res = res / x * (x - 1);//有没有遗漏

    return res;
}


int main()
{
    
    
    int n;
    cin >> n;
    while (n -- )
    {
    
    
        int x;
        cin >> x;
        cout << phi(x) << endl;
    }

    return 0;
}

AcWing 874. 筛法求欧拉函数
质数ii的欧拉函数即为phi[i] = i - 1:1 ~ i−1均与i互质,共i−1个。

phi[primes[j] * i]分为两种情况:
① i % primes[j] == 0时:primes[j]是i的最小质因子,也是primes[j] * i的最小质因子,因此1 - 1 / primes[j]这一项在phi[i]中计算过了,只需将基数NN修正为primes[j]倍,最终结果为phi[i] * primes[j]。
② i % primes[j] != 0:primes[j]不是i的质因子,只是primes[j] * i的最小质因子,因此不仅需要将基数NN修正为primes[j]倍,还需要补上1 - 1 / primes[j]这一项,因此最终结果phi[i] * (primes[j] - 1)。
作者:番茄酱
链接:https://www.acwing.com/solution/content/3952/
来源:AcWing
#include <iostream>

using namespace std;

typedef long long LL;

const int N = 1000010;


int primes[N], cnt;
int euler[N];
bool st[N];


void get_eulers(int n)
{
    
    
    euler[1] = 1;
    for (int i = 2; i <= n; i ++ )
    {
    
    
        if (!st[i])
        {
    
    
            primes[cnt ++ ] = i;
            euler[i] = i - 1;  //1到p-1都和p互质
        }
        for (int j = 0; primes[j] <= n / i; j ++ )
        {
    
    
            int t = primes[j] * i;
            st[t] = true;
            if (i % primes[j] == 0)//p[j]*i的所有质因子都出现在i的所有质因子当中
            {
    
    
                euler[t] = euler[i] * primes[j];//比i的所有质因子多了一个p[j]
                break;
            }
            euler[t] = euler[i] * (primes[j] - 1);
        }
    }
}


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

    get_eulers(n);

    LL res = 0;
    for (int i = 1; i <= n; i ++ ) res += euler[i];

    cout << res << endl;

    return 0;
}

猜你喜欢

转载自blog.csdn.net/Annabel_CM/article/details/109356704