欧拉函数详解

Posted 自为

tags:

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

欧拉函数

我们用$\\phi(n)$表示欧拉函数

定义:$\\phi(n)$表示对于整数$n$,小于等于$n$中与$n$互质的数的个数

性质

1.$\\phi(n)$为积性函数

证明:

此处证明需要用到下面计算方法1中的内容,建议先看后面再回过头来看这里

假设存在$p,q$,且$p*q=n$

将$n,p,q$进行质因数分解

$n=a_1^{p_1}*a_2^{p_2}...*a_k^{p_k}$

$p=a_1^{p_1}*a_2^{p_2}...*a_m^{p_m}$

$q=a_{m+1}^{p_{m+1}}*a_{m+2}^{m+2}...*a_k^{p_k}$

那么

$\\varphi \\left( n\\right) =n\\prod ^{k}_{i=1}\\left( 1-\\dfrac {1}{p_{i}}\\right)$

$\\varphi \\left( a\\right) =a\\prod ^{m}_{i=1}\\left( 1-\\dfrac {1}{p_{i}}\\right)$

$\\varphi \\left( b\\right) =b\\prod ^{k}_{i=m+1}\\left( 1-\\dfrac {1}{p_{i}}\\right)$

因为$n=a*b$

显然

$\\varphi \\left( n\\right) =\\varphi \\left( a\\right) \\varphi \\left( b\\right)$

这种方法也是常见的证明一个函数是积性函数的方法

 

2.$\\sum_{d|n}\\phi(d)=n$

3.$1$到$n$中与$n$互质的数的和为$n*\\dfrac{\\phi(n)}{2}(n>1)$

证明:若$gcd(n, i) = 1$,那么$gcd(n, n - i) = 1$

因此与$n$互质的数都是成对出现的。且每一对的和都为$n$

这样最终答案为$n * \\frac{\\phi(n)}{2}$

4. $a^{\\phi(n)} \\equiv 1 \\pmod n$

 

计算方法

$\\sqrt(n)$计算单值欧拉函数

假设我们需要计算$\\phi(n)$

分情况讨论

1.当$n=1$时

很明显,答案为$1$

2.当$n$为质数时

根据素数的定义,答案为$n-1$

(仅有$n$与$n$不互质)

3.当$n$为合数时

我们已经知道了$n$为素数的情况

不妨对$n$进行质因数分解

设$n=a_1^{p_1}*a_2^{p_2}...*a_k^{p_k}$

假设$k=1$

那么$\\phi(p^k)=p^k-p^{k-1}$

证明:

考虑容斥,与一个数互素的数的个数就是这个数减去与它不互素的数的个数

因为$p$是素数,所以在$p^k$中与其不互素的数为$1*p$,$2*p$....$p^{k-1}*p$,有$p^{k-1}$个

得证

 

当$k\\neq 1$时

$$\\phi(n)$$

$$=\\varphi \\left( a^{p_{1}}_{1}a^{p_{2}\\ldots }_{2}a^{Pk}_{k}\\right)$$

$$=\\prod ^{k}_{i=1}a^{P_i}-a^{P_{i}-1}_{i}$$

$$=\\prod ^{k}_{i=1}a^{Pi}_{i}(1-\\dfrac {1}{p_{i}})$$

$$=n*\\prod ^{k}_{i=1}(1-\\dfrac {1}{p_{i}})$$

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 1e7 + 10;
int p, ans = 1, N;
void GetPhi() {
    for(int i = 2; i * i <= p; i++) {
        if(p % i == 0) {
            int now = i - 1; p /= i;
            while(p % i == 0) now = now * i, p /= i;
            ans = ans * now;
        }
    }
    if(p != 1) ans *= (p - 1); 
}
int main() {
    cin >> p; N = p;
    GetPhi();
    cout << ans;
    return 0;
}

 

线性筛

因为欧拉函数是积性函数

因此可以使用线性筛法

性质1

若$p$为素数,则$\\varphi \\left( p\\right) =p-1$

证明:

在$1-p$中,只有$(p,p)\\neq1$

性质2

若$i\\ mod\\ p \\neq  0$,且$p$为素数

则$\\varphi \\left( i*p\\right) =\\varphi \\left( i\\right) *\\varphi \\left( p\\right)$

$=\\varphi \\left( i\\ast p\\right) =\\varphi \\left( i\\right) \\ast \\left( p-1\\right)$

这一步同时利用了性质1和欧拉函数的积性

性质3

若$i\\ mod \\ p = 0$,且$p$为素数,

则$\\varphi \\left( i\\ast p\\right) =\\varphi \\left( i\\right) \\ast p$

证明:

没怎么看懂,丢一个链接

http://blog.csdn.net/Lytning/article/details/24432651

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 3e5 + 10;
void GetPhi(int N) {
    static int phi[MAXN], vis[MAXN], prime[MAXN], tot = 0;
    for(int i = 2; i <= N; i++) {
        if(!vis[i]) prime[++tot] = i, phi[i] = i - 1;
        for(int j = 1; j <= tot && i * prime[j] <= N; j++) {
            vis[i * prime[j]] = 1;
            if(!(i % prime[j])) {phi[i * prime[j]] = phi[i] * prime[j]; break;}
            else phi[i * prime[j]] = phi[i] * (prime[j] - 1);
        }
    }
    while(cin >> N) cout << phi[N] << endl;
}
int main() {
    GetPhi(100);
    return 0;
}

例题

放几道水题

http://poj.org/problem?id=2407

题解

http://poj.org/problem?id=2478

题解

https://www.luogu.org/problemnew/show/P2158

题解

参考资料

数论学习笔记 欧拉函数 (一些性质和运用)内置杜教筛

 

以上是关于欧拉函数详解的主要内容,如果未能解决你的问题,请参考以下文章

递推求欧拉函数的最简单的详解

最大公约数之和欧拉函数

Unity3D 控制物体旋转详解 —— 自身绕轴旋转缓慢旋转鼠标控制旋转欧拉数和四元数的关系

欧拉函数知识点总结及代码模板及欧拉函数表

埃氏筛法与欧拉筛(超级详解)

欧拉函数及代码实现