欧拉函数

欧拉函数

定义

一组数 \(x_1,x_2,\dots,x_s\) 称为是模 \(m\) 的既约剩余系(简称缩系),如果对 \(\forall j,s \in Z,i\le j \le s,(x_j,m)=1\) ,并定义 \(\phi(m)=s\) ,即 \(\{1,2,3,\cdots,m\}\) 中与 \(m\) 互素的个数,\(\phi(n)\)称为欧拉函数。

通俗地讲,欧拉函数 \(\phi(n)\) 表示1~n中与n互质的数的个数。

举个例子:

在1~6中,只有 \(1\)\(5\) 两个数字与6互质,故 \(\phi(6)=2\)

在1~18中,有 \(1,2,5,7,11,13,17\) 一共6个数字与18互质,故 \(\phi(18)=6\)

性质

  1. 如果一个数 \(p\) 是质数,那么它的欧拉函数为 \(p-1\),也就是说1~p-1的所有数字均与 \(p\) 互质。

  2. \(m=m_1m_2(m\in \mathbb{N}^*)\),则有:若 \(m_1\)\(m_2\) 互质,则 \(\phi(m)=\phi(m_1)\phi(m_2)\);若 \(m_1\)\(m_2\) 不互质,则 \(\phi(m)=m_1\phi(m_2)\),其中 \(m_1\le m_2\).

  3. 对于 \(\forall m\in \mathbb{N}^*\),有

    \[\sum\limits_{d|m} \phi(d)=\sum\limits_{d|m}\phi\left(\frac{m}{d}\right) \]

  4. 欧拉定理:

    \[若\space a\space与\space m\space互质,则\space a^{\phi(m)}\equiv 1 (mod\space m). \]

公式

根据算术基本定理,一个数N可以被唯一分解为有限个质数之积的形式:

\[N=P_1^{\alpha_1}P_2^{\alpha_2}P_3^{\alpha_3}\cdots P_k^{\alpha_k} \]

在此基础上, \(\phi(N)\)的计算公式为:

\[\phi(N) = N \left(1-\frac{1}{P_1}\right) \left(1-\frac{1}{P_2}\right)\cdots \left(1-\frac{1}{P_k}\right) \]

举个例子:

\[6=2^1*3^1\quad\Rightarrow\quad \phi(6)=6*\left(1-\frac{1}{2}\right)\left(1-\frac{1}{3}\right)=6*\frac{1}{2}*\frac{2}{3}=2 \]

\[18=2^1*3^2\quad\Rightarrow\quad \phi(18)=18*\left(1-\frac{1}{2}\right)\left(1-\frac{1}{3}\right)=18*\frac{1}{2}*\frac{2}{3}=6 \]

证明

根据容斥原理

1.从 1~N 中去掉 \(P_1,P_2,...P_k\) 的所有倍数。(共减 \(C_k^1\) 项)

\[N-\frac{N}{P_1}-\frac{N}{P_2}-\cdots\frac{N}{P_k} \]

2.再加上所有 \(P_i*P_j\) 的倍数。(这些数字被重复去掉了,共加 \(C_k^2\) 项)

\[+\frac{N}{P_1P_2}+\frac{N}{P_1P_3}+\frac{N}{P_1P_4}+\cdots+\frac{N}{P_{k-1}P_k} \]

3.再减去所有 \(P_i*P_j*P_h\) 的倍数。(共减 \(C_k^3\) 项)

\[-\frac{N}{P_1P_2P_3}-\frac{N}{P_1P_2P_4}-\cdots-\frac{N}{P_{k-2}P_{k-1}P_k} \]

以此类推...

最终所得式子即为上述公式的展开式。

求一个数的欧拉函数

时间复杂度

直接用公式求解,决速步为分解质因数,因此时间复杂度为 \(O(\sqrt n)\).

代码

由于C++中 / 为整除运算,我们也不希望出现小数,因此将公式稍微变形,将 \(res\times \left(1-\frac{1}{P}\right)\) 的操作改为等价的 \(\frac{res}{P}\times (P-1)\) 操作。

int phi(int n) {
	int res = n, p = 2;
	while (n != 1) {
		if (n % p == 0) {
			res = res / p * (p - 1);
		while (n % p == 0)	n /= p;
		}
		p++;
	}
	return res;
}

求n以内的每个数的欧拉函数

思路:

利用素数线性筛(欧氏筛法),结合欧拉函数的一些性质,改写为一个线性的筛法。

时间复杂度:

\(O(n)\)

代码:

#include <iostream>
using namespace std;
const int N = 1e6 + 5;
int p[N], t;		//质数及下标
int phi[N];			//欧拉函数
bool s[N];			//是否为合数

void get_euler(int n) {		//计算n以内的欧拉函数
	phi[1] = 1;
	for (int i = 2; i <= n; i++) {
		if (!s[i]) {
			p[++t] = i;
			phi[i] = i - 1;
		}
		for (int j = 1; p[j] <= n / i; j++) {
			s[i * p[j]] = true;
			if (i % p[j] == 0) {
				phi[i * p[j]] = phi[i] * p[j];
				break;
			}
			phi[i * p[j]] = phi[i] * (p[j] - 1);
		}
	}
}

代码解释:

第13行:\(i\) 为质数,则 \(\phi(i) = i-1\).

第18行:此时 \(p[j]\)\(i\) 的最小质因数,若:

\[\begin{align*} i&=P_1^{\alpha_1}P_2^{\alpha_2}P_3^{\alpha_3}\cdots P_k^{\alpha_k} \\ \phi(i) &=i \left(1-\frac{1}{P_1}\right) \left(1-\frac{1}{P_2}\right)\cdots \left(1-\frac{1}{P_k}\right) \end{align*} \]

则:

\[\begin{align*} i*p[j]&=P_1^{\alpha_1+1}P_2^{\alpha_2}P_3^{\alpha_3}\cdots P_k^{\alpha_k} \\ \phi(i*p[j])&=i\times p[j] \times\left(1-\frac{1}{P_1}\right) \left(1-\frac{1}{P_2}\right)\cdots \left(1-\frac{1}{P_k}\right) \end{align*} \]

因此:

\[\phi(i*p[j])=p[j]\times \phi(i) \]

第21行:此时 \(p[j]\) 小于 \(i\) 的最小质因数,若:

\[\begin{align*} i&=P_1^{\alpha_1}P_2^{\alpha_2}P_3^{\alpha_3}\cdots P_k^{\alpha_k} \\ \phi(i) &=i \left(1-\frac{1}{P_1}\right) \left(1-\frac{1}{P_2}\right)\cdots \left(1-\frac{1}{P_k}\right) \end{align*} \]

则:

\[\begin{align*} i*p[j]&=P_1^{\alpha_1}P_2^{\alpha_2}P_3^{\alpha_3}\cdots P_k^{\alpha_k}\cdot p[j] \\ \phi(i*p[j])&=i\times p[j] \times\left(1-\frac{1}{P_1}\right) \left(1-\frac{1}{P_2}\right)\cdots \left(1-\frac{1}{P_k}\right) \cdot \left(1-\frac{1}{p[j]}\right) \end{align*} \]

因此:

\[\phi(i*p[j])=\phi(i)\times p[j]\times \left(1-\frac{1}{p[j]}\right)=\phi(i)\times (p[j]-1) \]

posted @ 2025-04-11 20:40  H_Elden  阅读(97)  评论(0)    收藏  举报