【欧拉函数】 欧拉函数计算及打表
文章目錄
- 一.歐拉函數簡介
- 二.歐拉函數計算
- 三.歐拉函數值打表
- 四.練手題目
一.歐拉函數簡介
在數論中,對正整數n,歐拉函數是小于或等于n的正整數中與n互質的數的數目(因此φ(1)=1)。此函數以其首名研究者歐拉命名(Euler’s totient function),它又稱為Euler’s totient function、φ函數、歐拉商數等。 例如φ(8)=4,因為1,3,5,7均和8互質。
注:a,b互質即gcd(a,b)=1
二.歐拉函數計算
計算公式φ(n)=n?∏i=1k(1?1pi)φ(n)=n\cdot \prod_{i=1}^k(1-\frac{1}{p_i})φ(n)=n?∏i=1k?(1?pi?1?),其中,pi為n的質因數
即根據質因數分解定理,將一個數n分解成有限個質數的乘積:n=p1a1?p2a2?p3a3?p4a4????n=p_1^{a1}\cdot p_2^{a2}\cdot p_3^{a3}\cdot p_4^{a4}\cdot\cdot\cdot\cdotn=p1a1??p2a2??p3a3??p4a4?????
則,φ(n)=n?(1?1p1)?(1?1p2)?(1?1p3)????φ(n)=n\cdot (1-\frac{1}{p_1})\cdot (1-\frac{1}{p_2})\cdot (1-\frac{1}{p_3})\cdot\cdot\cdot\cdotφ(n)=n?(1?p1?1?)?(1?p2?1?)?(1?p3?1?)????
例:
6=2*3
則,φ(6)=6?(1?12)?(1?13)=2φ(6)=6\cdot(1-\frac{1}{2})\cdot(1-\frac{1}{3})=2φ(6)=6?(1?21?)?(1?31?)=2
即,6以內有2個數和6互質
驗證:1、5和6互質,2、3、4、6都是6
的因數
顯而易見地,當n為質數時,φ(n)=n?1φ(n)=n-1φ(n)=n?1
歐拉函數計算模板:
素因數分解即可
int Euler(int N){int ret=N;for(int i=2;i*i<=N;i++)if(N%i==0){ret=ret*(i-1)/i;while(N%i==0)N/=i;}if(N>1) ret=ret*(N-1)/N;return ret; }補一下計算歐拉函數值公式的證明,不想看的可以跳過:
在計算1~ N中與N互質的個數時,先設置初始值為N,即假設1~ N都與N互質。
①φ(N)=N①φ(N)=N①φ(N)=N
若p是數N的一個質因子,則p以及p的倍數必然與N起碼包含一個共同的因子:p,即它們的gcd值>1,故p及p的倍數不可能與N互質
所以應減去這部分,即:
②φ(N)=N?Np=N(1?1p)②φ(N)=N-\frac{N}{p}=N(1-\frac{1}{p})②φ(N)=N?pN?=N(1?p1?)
1~N中共有p,2p,3p……N共Np\frac{N}{p}pN?個p的倍數(N也是p的倍數)
現假設N還有1個質因子q,則利用容斥原理,得:
③φ(N)=N?Np?Nq+Npq=N[(1?1p)?1q(1?1p)]=N(1?1p)(1?1q)③φ(N)=N-\frac{N}{p}-\frac{N}{q}+\frac{N}{pq}=N[(1-\frac{1}{p})-\frac{1}{q}(1-\frac{1}{p})]=N(1-\frac{1}{p})(1-\frac{1}{q})③φ(N)=N?pN??qN?+pqN?=N[(1?p1?)?q1?(1?p1?)]=N(1?p1?)(1?q1?)
……
得歐拉函數計算公式:
φ(n)=n?(1?1p1)?(1?1p2)?(1?1p3)????φ(n)=n\cdot (1-\frac{1}{p_1})\cdot (1-\frac{1}{p_2})\cdot (1-\frac{1}{p_3})\cdot\cdot\cdot\cdotφ(n)=n?(1?p1?1?)?(1?p2?1?)?(1?p3?1?)????
三.歐拉函數值打表
預備知識:
歐拉函數為積性函數,即:
若m,n互質,φ(mn)=φ(m)?φ(n)φ(mn)=φ(m)\cdotφ(n)φ(mn)=φ(m)?φ(n)
例:φ(12)=φ(3)?φ(4)=2?2=4φ(12)=φ(3)\cdot φ(4)=2\cdot 2=4φ(12)=φ(3)?φ(4)=2?2=4
證明:
回想歐拉函數的計算方法:φ(n)=n?(1?1p1)?(1?1p2)?(1?1p3)????φ(n)=n\cdot (1-\frac{1}{p_1})\cdot (1-\frac{1}{p_2})\cdot (1-\frac{1}{p_3})\cdot\cdot\cdot\cdotφ(n)=n?(1?p1?1?)?(1?p2?1?)?(1?p3?1?)????
因為m和n互質,所以m和n沒有共同的因子,則mn的所有質因子其實就是m的質因子加上n的質因子,再想想歐拉函數的計算方法,φ(mn)φ(mn)φ(mn)可以被拆為φ(m)?φ(n)φ(m)\cdotφ(n)φ(m)?φ(n)
這個特性為我們揭示了一個數的歐拉函數值與其質因數歐拉函數值的關系,我們可以利用其來篩出歐拉函數值:
用phi數組儲存歐拉函數值(phi即φ的英文)
①phi數組初始化為0,表示未處理(phi[1]的值為1)
②從2開始循環,在處理一個數的同時處理其所有倍數,令它們乘上i?1i\frac{i-1}{i}ii?1?即(1?1i)(1-\frac{1}{i})(1?i1?),反過來理解每個數都會被其質因數這么處理一次
③兩個if( !phi[j] )需要理解,先說第二個:每個數如果沒被處理過則讓它先等于該數本身(之前說了phi值為0表示一個數還沒被處理過)。這很容易理解,因為求歐拉函數值的公式為:φ(n)=n?(1?1p1)?(1?1p2)?(1?1p3)????φ(n)=n\cdot (1-\frac{1}{p_1})\cdot (1-\frac{1}{p_2})\cdot (1-\frac{1}{p_3})\cdot\cdot\cdot\cdotφ(n)=n?(1?p1?1?)?(1?p2?1?)?(1?p3?1?)????,之所以沒被處理過才進行這步操作是為了保證這步操作只被執行一次。
④第一個 if( !phi[j] ) 則是為了只讓質因數去對它的倍數進行操作:一個數如果是合數,它必然被之前的素數處理過,所以phi的值不可能是0,這樣就保證了只有素數才會對其倍數進行處理
可以發現這個做法和素數篩很像。
代碼如下:
#include <cstdio> #include <algorithm> #include <iostream> using namespace std;int phi[1000010];void Euler_excel(int n){phi[1]=1;for(int i=2;i<=n;i++) phi[i]=0;for(int i=2;i<=n;i++)if(!phi[i]){for(int j=i;j<=n;j+=i){if(!phi[j]) phi[j]=j;phi[j]=phi[j]/i*(i-1);}} }四.練手題目
1 .
計算歐拉函數值模板題:HDU-1286
2 .
歐拉函數打表模板題:LightOJ-1370
題解:傳送門
3 .
Visible Lattice Points: POJ-3090
題解:傳送門
總結
以上是生活随笔為你收集整理的【欧拉函数】 欧拉函数计算及打表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android游戏开发项目实战——数独
- 下一篇: 手把手教你实现解密数独的web应用程序