欧拉函数(Euler’s totient function), φ ( n ) \varphi(n) φ(n) ,表示的是小于等于 n n n 和 n n n 互质的数的个数。
比如说 φ ( 6 ) = 2 \varphi(6) = 2 φ(6)=2 。
当 n 是质数的时候,显然有 φ ( n ) = n − 1 \varphi(n) = n - 1 φ(n)=n−1 。
利用唯一分解定理,我们可以把一个整数唯一地分解为质数幂次的乘积,
设 n = p 1 k 1 p 2 k 2 ⋯ p s k s n = p_1^{k_1}p_2^{k_2} \cdots p_s^{k_s} n=p1k1p2k2⋯psks ,其中 p i p_i pi 是质数,那么定义 φ ( n ) = n × ∏ i = 1 s p i − 1 p i \varphi(n) = n \times \prod_{i = 1}^s{\frac{p_i - 1}{p_i}} φ(n)=n×∏i=1spipi−1
欧拉函数的一些神奇性质(不涉及证明)
欧拉函数是积性函数。
积性是什么意思呢?如果有 gcd ( a , b ) = 1 \gcd(a, b) = 1 gcd(a,b)=1 ,那么 φ ( a ∗ b ) = φ ( a ) ∗ φ ( b ) \varphi(a * b) = \varphi(a) * \varphi(b) φ(a∗b)=φ(a)∗φ(b) 。
特别地,当 n n n 是奇数时 φ ( 2 n ) = φ ( n ) \varphi(2n) = \varphi(n) φ(2n)=φ(n) 。
∑ d ∣ n φ ( d ) = n \sum_{d | n}{\varphi(d)} = n ∑d∣nφ(d)=n
若 n = p k n = p^k n=pk ,其中 p p p 是质数,那么 φ ( n ) = p k − p k − 1 \varphi(n) = p^k - p^{k - 1} φ(n)=pk−pk−1 。 (根据定义可知)
如何求欧拉函数值
如果只要求一个数的欧拉函数值,那么直接根据定义质因数分解的同时求就好了。
int euler_phi(int n) {//暴力求法
int m = int(sqrt(n + 0.5));
int ans = n;
for (int i = 2; i <= m; i++)
if (n % i == 0) {
ans = ans / i * (i - 1);
while (n % i == 0) n /= i;
}
if (n > 1) ans = ans / n * (n - 1);
return ans;
}
//线性筛欧拉函数 O(n)求解,多用于求多个数的欧拉函数值
const int N = 1e5;
int phi[N+10], prime[N+10], tot, ans;
bool vis[N+10];
void getphi()
{
int i,j;
phi[1] = 1;
for(i = 2; i <= N; ++i) //相当于分解质因式的逆过程
{
if(!vis[i])
{
prime[++tot] = i;//筛素数的时候首先会判断i是否是素数。
phi[i] = i - 1;//当 i 是素数时 phi[i]=i-1
}
for(j = 1; j <= tot; ++j)
{
if(i*prime[j] > N)
break;
vis[i*prime[j]] = 1;//确定i*prime[j]不是素数
if(i % prime[j] == 0)//接着我们会看prime[j]是否是i的约数
{
phi[i*prime[j]] = phi[i] * prime[j];
break;
}
else
phi[i*prime[j]] = phi[i] * (prime[j]-1);
}
}
}
欧拉定理
与欧拉函数紧密相关的一个定理就是欧拉定理。其描述如下:
若 gcd ( a , m ) = 1 \gcd(a, m) = 1 gcd(a,m)=1 ,则 a φ ( m ) ≡ 1 ( m o d m ) a^{\varphi(m)} \equiv 1 \pmod{m} aφ(m)≡1(modm) 。
扩展欧拉定理