欧拉函数(C++)

欧拉函数

定义

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

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

\qquad 举个例子:

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

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

性质

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

  2. m = m 1 m 2 ( m ∈ N ∗ ) m=m_1m_2(m\in \mathbb{N}^*) m=m1m2(mN),则有:若 m 1 m_1 m1 m 2 m_2 m2 互质,则 ϕ ( m ) = ϕ ( m 1 ) ϕ ( m 2 ) \phi(m)=\phi(m_1)\phi(m_2) ϕ(m)=ϕ(m1)ϕ(m2);若 m 1 m_1 m1 m 2 m_2 m2 不互质,则 ϕ ( m ) = m 1 ϕ ( m 2 ) \phi(m)=m_1\phi(m_2) ϕ(m)=m1ϕ(m2),其中 m 1 ≤ m 2 m_1\le m_2 m1m2.

  3. 对于 ∀ m ∈ N ∗ \forall m\in \mathbb{N}^* mN,有
    ∑ d ∣ m ϕ ( d ) = ∑ d ∣ m ϕ ( m d ) \sum\limits_{d|m} \phi(d)=\sum\limits_{d|m}\phi\left(\frac{m}{d}\right) dmϕ(d)=dmϕ(dm)

  4. 欧拉定理:
    若  a  与  m  互质,则  a ϕ ( m ) ≡ 1 ( m o d   m ) . 若\space a\space与\space m\space互质,则\space a^{\phi(m)}\equiv 1 (mod\space m).  a  m 互质,则 aϕ(m)1(mod m).

公式

\qquad 根据算术基本定理,一个数N可以被唯一分解为有限个质数之积的形式:
N = P 1 α 1 P 2 α 2 P 3 α 3 ⋯ P k α k N=P_1^{\alpha_1}P_2^{\alpha_2}P_3^{\alpha_3}\cdots P_k^{\alpha_k} N=P1α1P2α2P3α3Pkαk
\qquad 在此基础上, ϕ ( N ) \phi(N) ϕ(N)的计算公式为:
ϕ ( N ) = N ( 1 − 1 P 1 ) ( 1 − 1 P 2 ) ⋯ ( 1 − 1 P k ) \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) ϕ(N)=N(1P11)(1P21)(1Pk1)
\qquad 举个例子:
6 = 2 1 ∗ 3 1 ⇒ ϕ ( 6 ) = 6 ∗ ( 1 − 1 2 ) ( 1 − 1 3 ) = 6 ∗ 1 2 ∗ 2 3 = 2 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 6=2131ϕ(6)=6(121)(131)=62132=2

18 = 2 1 ∗ 3 2 ⇒ ϕ ( 18 ) = 18 ∗ ( 1 − 1 2 ) ( 1 − 1 3 ) = 18 ∗ 1 2 ∗ 2 3 = 6 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 18=2132ϕ(18)=18(121)(131)=182132=6

证明

\qquad 根据容斥原理

\qquad 1.从 1~N 中去掉 P 1 , P 2 , . . . P k P_1,P_2,...P_k P1,P2,...Pk 的所有倍数。(共减 C k 1 C_k^1 Ck1 项)
N − N P 1 − N P 2 − ⋯ N P k N-\frac{N}{P_1}-\frac{N}{P_2}-\cdots\frac{N}{P_k} NP1NP2NPkN
\qquad 2.再加上所有 P i ∗ P j P_i*P_j PiPj 的倍数。(这些数字被重复去掉了,共加 C k 2 C_k^2 Ck2 项)
+ N P 1 P 2 + N P 1 P 3 + N P 1 P 4 + ⋯ + N P k − 1 P k +\frac{N}{P_1P_2}+\frac{N}{P_1P_3}+\frac{N}{P_1P_4}+\cdots+\frac{N}{P_{k-1}P_k} +P1P2N+P1P3N+P1P4N++Pk1PkN
\qquad 3.再减去所有 P i ∗ P j ∗ P h P_i*P_j*P_h PiPjPh 的倍数。(共减 C k 3 C_k^3 Ck3 项)
− N P 1 P 2 P 3 − N P 1 P 2 P 4 − ⋯ − N P k − 2 P k − 1 P k -\frac{N}{P_1P_2P_3}-\frac{N}{P_1P_2P_4}-\cdots-\frac{N}{P_{k-2}P_{k-1}P_k} P1P2P3NP1P2P4NPk2Pk1PkN
\qquad 以此类推…

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

求一个数的欧拉函数

时间复杂度

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

代码

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

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以内的每个数的欧拉函数

思路:

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

时间复杂度:

O ( n ) O(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);
		}
	}
}

代码解释:

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

\qquad 第18行: 此时 p [ j ] p[j] p[j] i i i 的最小质因数,若:
i = P 1 α 1 P 2 α 2 P 3 α 3 ⋯ P k α k ϕ ( i ) = i ( 1 − 1 P 1 ) ( 1 − 1 P 2 ) ⋯ ( 1 − 1 P k ) 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) i=P1α1P2α2P3α3Pkαkϕ(i)=i(1P11)(1P21)(1Pk1)
\qquad 则:
i ∗ p [ j ] = P 1 α 1 + 1 P 2 α 2 P 3 α 3 ⋯ P k α k ϕ ( i ∗ p [ j ] ) = i × p [ j ] × ( 1 − 1 P 1 ) ( 1 − 1 P 2 ) ⋯ ( 1 − 1 P k ) 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) ip[j]=P1α1+1P2α2P3α3Pkαkϕ(ip[j])=i×p[j]×(1P11)(1P21)(1Pk1)
\qquad 因此:
ϕ ( i ∗ p [ j ] ) = p [ j ] × ϕ ( i ) \phi(i*p[j])=p[j]\times \phi(i) ϕ(ip[j])=p[j]×ϕ(i)
\qquad 第21行: 此时 p [ j ] p[j] p[j] 小于 i i i 的最小质因数,若:
i = P 1 α 1 P 2 α 2 P 3 α 3 ⋯ P k α k ϕ ( i ) = i ( 1 − 1 P 1 ) ( 1 − 1 P 2 ) ⋯ ( 1 − 1 P k ) 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) i=P1α1P2α2P3α3Pkαkϕ(i)=i(1P11)(1P21)(1Pk1)
\qquad 则:
i ∗ p [ j ] = P 1 α 1 P 2 α 2 P 3 α 3 ⋯ P k α k ⋅ p [ j ] ϕ ( i ∗ p [ j ] ) = i × p [ j ] × ( 1 − 1 P 1 ) ( 1 − 1 P 2 ) ⋯ ( 1 − 1 P k ) ⋅ ( 1 − 1 p [ j ] ) 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) ip[j]=P1α1P2α2P3α3Pkαkp[j]ϕ(ip[j])=i×p[j]×(1P11)(1P21)(1Pk1)(1p[j]1)
\qquad 因此:
ϕ ( i ∗ p [ j ] ) = ϕ ( i ) × p [ j ] × ( 1 − 1 p [ j ] ) = ϕ ( i ) × ( p [ j ] − 1 ) \phi(i*p[j])=\phi(i)\times p[j]\times \left(1-\frac{1}{p[j]}\right)=\phi(i)\times (p[j]-1) ϕ(ip[j])=ϕ(i)×p[j]×(1p[j]1)=ϕ(i)×(p[j]1)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值