欧拉函数、定理学习笔记
欧拉函数
定义
所有小于等于 x x 的数中与 x x 互质 的数的个数。
符号: φ ( x ) φ ( x )
通项公式
p i p i 表示 x x 的质因数,n n 表示 x x 的质因数个数。
φ ( x ) = x n ∏ i = 1 ( 1 − 1 p i ) φ ( x ) = x ∏ i = 1 n ( 1 − 1 p i )
欧拉函数的性质
对于质数 x x ,φ ( x ) = x − 1 φ ( x ) = x − 1
若 x x ,y y 互质,则 φ ( x ) × φ ( y ) = φ ( x × y ) φ ( x ) × φ ( y ) = φ ( x × y )
这条性质属于积性函数,即任意满足有 互质 的数 a , b a , b 时,恒有 f ( a × b ) = f ( a ) × f ( b ) f ( a × b ) = f ( a ) × f ( b )
(怎么证明我是真的不会,如果真想知道可以看下这个 )
如果 n n 为奇数,则 φ ( n × 2 ) = φ ( n ) φ ( n × 2 ) = φ ( n )
因为 n n 为奇数,所以 n n 与 2 互质,且 φ ( 2 ) = 1 φ ( 2 ) = 1 ,所以上式成立。
如果 x x 为质数,则φ ( x k ) = x k − x k − 1 φ ( x k ) = x k − x k − 1
因为与 x k x k 不互质的数只有 x x 的倍数,而 x k x k 中 x x 的倍数有 x k − 1 x k − 1 个。
如果 3 ≤ x 3 ≤ x ,则 φ ( x ) φ ( x ) 的值为偶数。
因为 gcd ( x , n ) = gcd ( n − x , n ) gcd ( x , n ) = gcd ( n − x , n ) ,更相减损术证明,与 x x 互质的数是成对存在 的,且每一对中的两个数之和为 x x 。
x − 1 ∑ i = 1 , ( i , x ) = 1 i = φ ( x ) × x 2 ( 2 ≤ x ) ∑ i = 1 , ( i , x ) = 1 x − 1 i = φ ( x ) × x 2 ( 2 ≤ x )
通过上面的证明可知,每一对与 x x 互质的数的和为 x x ,总共有 φ ( x ) 2 φ ( x ) 2 对。
x = ∑ i | x φ ( i ) x = ∑ i | x φ ( i ) ,即 x x 的因数(包括1和它自己)的欧拉函数之和等于 x x 。
这条性质又叫欧拉反演 。
证明:
定义函数 f ( n ) = ∑ i | n φ ( i ) f ( n ) = ∑ i | n φ ( i )
f ( n ) f ( n ) 是积性函数,证明: f ( n ) × f ( m ) = ∑ i | n φ ( i ) × ∑ j | m φ ( j ) = ∑ i | n ∑ j | m φ ( i ) φ ( j ) = ∑ i | n ∑ j | m φ ( i × j ) = ∑ d | n m φ ( d ) = f ( n m ) f ( n ) × f ( m ) = ∑ i | n φ ( i ) × ∑ j | m φ ( j ) = ∑ i | n ∑ j | m φ ( i ) φ ( j ) = ∑ i | n ∑ j | m φ ( i × j ) = ∑ d | n m φ ( d ) = f ( n m )
f ( p k ) = φ ( 1 ) + φ ( p ) + φ ( p 2 ) + ⋯ + φ ( p k ) = 1 + ( p − 1 ) + ( p 2 − p ) + ⋯ + ( p k − p k − 1 ) = p k f ( p k ) = φ ( 1 ) + φ ( p ) + φ ( p 2 ) + ⋯ + φ ( p k ) = 1 + ( p − 1 ) + ( p 2 − p ) + ⋯ + ( p k − p k − 1 ) = p k
n = p k 1 1 × p k 2 2 × ⋯ × p k m m n = p 1 k 1 × p 2 k 2 × ⋯ × p m k m
f ( n ) = f ( p k 1 1 ) × f ( p k 2 2 ) × ⋯ × p k m m = p k 1 1 × p k 2 2 × ⋯ × p k m m = n f ( n ) = f ( p 1 k 1 ) × f ( p 2 k 2 ) × ⋯ × p m k m = p 1 k 1 × p 2 k 2 × ⋯ × p m k m = n
求欧拉函数
求单个数的欧拉函数
直接根据之前的通式 φ ( x ) = x ∏ n i = 1 ( 1 − 1 p i ) φ ( x ) = x ∏ i = 1 n ( 1 − 1 p i ) 计算即可。
其中有以下几点细节:
如果以 √ n n 为上界分解质因数之后得到的值不是 1 1 ,说明 n n 有一个大于 √ n n 的质因数,要再进行一次计算。
对于通项公式中 ( 1 − 1 p i ) ( 1 − 1 p i ) 这一项,在代码实现中将其转化为 p i − 1 p i p i − 1 p i 。
int phi ( int x) {
int ans= x;
for ( int i= 2 ; i* i<= x; i++ )
if ( x% i== 0 ) {
ans= ans/ i* ( i- 1 ) ;
while ( x% i== 0 ) x/= i;
}
if ( x> 1 ) ans= ans/ x* ( x- 1 ) ;
return ans;
}
预处理欧拉函数
以下用 p i p i 表示数字 i i 的欧拉函数值,即 φ ( i ) φ ( i ) 。
O ( n log 2 ( log 2 n ) ) O ( n log 2 ( log 2 n ) ) 的筛法:
基本上不会被卡,而且比较好写的筛法。
先把所有 p i p i 初始化为 i i 。
对于当前枚举到的数 i i ,如果 p i = i p i = i ,那么 i i 为质数,并对之后包括 i i 在内的的倍数进行更新。
更新就是根据上面的通项公式,对于 p j p j ,就变为 p j ⋅ i − 1 i p j ⋅ i − 1 i
# define L ( i, j, k) for ( int i= ( j) ; i<= ( k) ; i++ )
# define ll ( i, j, k, l) for ( int i= ( j) ; i<= ( k) ; i+= ( l) )
L ( i, 1 , n) p[ i] = i;
L ( i, 2 , n) if ( p[ i] == i)
ll ( j, i, n, i) p[ j] = p[ j] / i* ( i- 1 ) ;
预先规定:
s i s i 表示筛出的第 i i 个质数。
f i f i 表示数字 i i 的最小质因数。
参考筛素数的线性筛,当筛到数字 i i 时,小于 i i 的数的欧拉函数和小于 i i 的质数已经筛出,利用 i i 和 s s 向后更新。
对于数字 i i ,如果此时 f i = 0 f i = 0 ,说明这个数的最小质因数不会在 [ 2 , i − 1 ] [ 2 , i − 1 ] 的范围内出现,也易得数字 i i 是个质数,根据前一篇博客中写到的欧拉函数性质可知,此时 φ ( i ) = i − 1 φ ( i ) = i − 1
所以,如果数字 i i 为质数:
将 i i 加入筛出的素数表。
f i = i f i = i ,质数的最小质因数是自身。
更新 p i p i 的值为 i − 1 i − 1 。
接下来,无论 i i 是否为质数,直接在素数表中枚举 s j s j 。
如果 i mod s j ! = 0 i mod s j ! = 0 ,可知 ( i , s j ) = 1 ( i , s j ) = 1 ,此时有 p i × s j = p i × p s j = p i × ( s j − 1 ) p i × s j = p i × p s j = p i × ( s j − 1 )
如果 i mod s j = 0 i mod s j = 0 ,此时 p i × s j = p i × s j p i × s j = p i × s j
同时更新 f s j × i = s j f s j × i = s j
证明:
i mod s j = 0 i mod s j = 0 时无法直接计算的原因是两个数不互质。
假设 i × p j = A × p m − 1 j × p j = p m j i × p j = A × p j m − 1 × p j = p j m
若 x x 是质数,φ ( x k ) = x k − x k − 1 φ ( x k ) = x k − x k − 1
因为 φ ( i × p j ) = φ ( A ) × φ ( p m j ) = φ ( A ) × φ ( p m − 1 j ) × p φ ( i × p j ) = φ ( A ) × φ ( p j m ) = φ ( A ) × φ ( p j m − 1 ) × p
其中 A × p m − 1 j = i A × p j m − 1 = i
所以 φ ( A ) × φ ( p m − 1 j ) = φ ( i ) φ ( A ) × φ ( p j m − 1 ) = φ ( i )
联立得 φ ( i × p j ) = φ ( A ) × φ ( p m − 1 j ) × p = φ ( i ) × p j φ ( i × p j ) = φ ( A ) × φ ( p j m − 1 ) × p = φ ( i ) × p j
得证。
代码实现:
if ( x== 1 ) return 0 ; p[ 1 ] = 1 ;
for ( int i= 2 ; i< n; i++ ) {
if ( ! f[ i] ) s[ ++ tp] = i, p[ i] = i- 1 , f[ i] = i;
for ( int j= 1 ; j<= tp; j++ ) {
if ( s[ j] * i> n|| s[ j] > f[ i] ) break ; f[ s[ j] * i] = s[ j] ;
if ( s[ j] < f[ i] ) p[ s[ j] * i] = ( s[ j] - 1 ) * p[ i] ;
else p[ s[ j] * i] = s[ j] * p[ i] ;
}
}
欧拉定理
若 gcd ( a , n ) = 1 gcd ( a , n ) = 1 ,则 a φ ( n ) ≡ 1 ( mod n ) a φ ( n ) ≡ 1 ( mod n )
证明:
从 1 到 n n 中,与 n n 互质的数为 φ ( n ) φ ( n ) 个,将这些数放入集合 x x 中,表示为 x 1 , x 2 , … , x φ ( n ) x 1 , x 2 , … , x φ ( n ) 。
再另外设一个集合 m m ,其中的元素 m 1 = a × x 1 m 1 = a × x 1 m 2 = a × x 2 m 2 = a × x 2 … … … … … … m φ ( n ) = a × x φ ( n ) m φ ( n ) = a × x φ ( n )
接下来要证明两个推理。
集合 m m 中的任意两个数模 n n 的余数不同 ,即不存在 m a , m b m a , m b 满足 m a ≡ m b ( mod n ) m a ≡ m b ( mod n )
用反证法 证明。
假设存在 m a , m b m a , m b 满足 m a ≡ m b ( mod n ) m a ≡ m b ( mod n ) ,即 ( m a − m b ) ÷ n = k ( m a − m b ) ÷ n = k
所以 m a − m b = n × k m a − m b = n × k
将集合 m m 中的数用集合 x x 中的数表示 a × x a − a × x b = n × k a × x a − a × x b = n × k
也就是 a × ( x a − x b ) = n × k a × ( x a − x b ) = n × k
因为已知 a a 与 n n 互质,所以式子转化为 ( x a − x b ) mod n = 0 ( x a − x b ) mod n = 0
但是因为已知 x a , x b < n x a , x b < n ,即 x a − x b < n x a − x b < n
所以上述式子均不成立,得证。
集合 m m 的数除以 n n 的余数都与 n n 互质。
首先已知 m i = a × x i m i = a × x i 。
其次已知 a a 与 n n 互质,x i x i 与 n n 互质,所以 m i m i 也就是 a × x i a × x i 与 n n 互质。
所以带入欧几里得算法(辗转相除法) 中推一步就行。
gcd ( a × x i , n ) = gcd ( m i , n ) = gcd ( n , m i mod n ) = 1 gcd ( a × x i , n ) = gcd ( m i , n ) = gcd ( n , m i mod n ) = 1
得证。
接下来开始推式子。
集合 m m 中的每个元素分别对应集合 x x 中的每个数同余。
因为第二个推理得到,m m 集合中的每个元素模 n n 的结果都与 n n 互质,这与 x x 中的数对应。
表示出来就是m i ≡ x i ( mod n ) m i ≡ x i ( mod n )
由此可得m 1 × m 2 × ⋯ × m φ ( n ) ≡ x 1 × x 2 × ⋯ × x φ ( n ) ( mod n ) m 1 × m 2 × ⋯ × m φ ( n ) ≡ x 1 × x 2 × ⋯ × x φ ( n ) ( mod n )
把集合 m m 中所有数都转换成集合 x x 中的数乘以 a a 的形式 a φ ( n ) × x 1 × x 2 × ⋯ × x φ ( n ) = x 1 × x 2 × ⋯ × x φ ( n ) ( mod n ) a φ ( n ) × x 1 × x 2 × ⋯ × x φ ( n ) = x 1 × x 2 × ⋯ × x φ ( n ) ( mod n )
移项可得 ( a φ ( n ) − 1 ) × x 1 × x 2 × ⋯ × x φ ( n ) ≡ 0 ( mod n ) ( a φ ( n ) − 1 ) × x 1 × x 2 × ⋯ × x φ ( n ) ≡ 0 ( mod n )
因为上面式子中的x 1 , x 2 … x φ ( n ) x 1 , x 2 … x φ ( n ) 均与 n n 互质,所以相乘的结果也与 n n 互质。
所以 a φ ( n ) − 1 ≡ 0 ( mod n ) a φ ( n ) − 1 ≡ 0 ( mod n )
即a φ ( n ) ≡ 1 ( mod n ) a φ ( n ) ≡ 1 ( mod n )
Q.E.D
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)