歐拉函數定義:phi(n) = 1到n中與n互質的數的個數
有公式: phi(n) = n* ∏ ( 1 - 1/pi ) 其中p為n的所有質因子,每個質因子只算一次
下面是證明:
1. 當n為質數,顯然phi(n) = n-1
2. 當n=p^k ,其中p為素數
與n不互質的數必定有p因子,把p提出來
於是不互質的數有{ p*1, p*2, p*3, ......, p*p^(k-1) }
於是互質的數即phi(n) = p^k - p^(k-1) = p^k * ( 1 - 1/p )
3. 當n= (x^a)*(y^a), 其中x和y為不相同的素數
有phi(n*m)=phi(m)*phi(n) , 當m和n互質
證明這個之前先證明 ( {1, 2, 3, 4, ....n } , {1, 2, 3, 4, ...... m }) 與 {1, 2, 3, 4, ...... m*n } 一一對應 (m,n互質)
①從m*n到(m,n)的唯一性
m*n中的x, x%m和x%n有唯一值
②從(m,n)到 m*n的唯一性
設從m中取x,x%m=r
則x對應m*n中的f可能值為 {r, m+r, 2m+r, 3m+r, .... (n-1)*m+r }
這n個數組成了n的完全剩余系
因為這n個數兩兩之間的差值可表示為 k* m (k<n)
則 (k*m)%n=0不成立( k<n , 而gcd(m,n)=1 即 m不提供n的因子 )
即每個數對n取模兩兩不同,則組成n的完全剩余系
因此假設再從n中取y, (x,y)可唯一確定一個m*n中的值
(似乎適用於中國剩余定理)可拓展到多維,即多個互質量
再看,(當m和n互質)只要x與m互質且x與n互質則x與m*n互質
任何與m互質的數x除以m的余數即(x%m)也必然與m互質,反之也如此
所以從(1...n)和(1...m)分別取x與n互質,y與m互質,則會唯一對應一個m*n中的值f 與m*n互質
而每個與(1...m*n)互質的值 f 都會唯一對應一個 (1...n)中與n互質的x和一個(1...m)中與m互質的y
所以phi(m*n) = phi(m) * phi(n) , (m,n互質)
證明完畢
那么這樣,對於要求歐拉值的n,將他因數分解成 pi^ai, 而 phi(pi^ai )= pi^ai ( 1 - 1/pi )
再將pi相乘得到n,就可以得出公式 phi(n) = n* ∏ ( 1 - 1/pi )
代碼:
long long eular(long long n) { long long ans = n; for(int i = 2; i*i <= n; i++) { if(n % i == 0) { ans −= ans/i; while(n % i == 0) n /= i; } } if(n > 1)ans −= ans/n; return ans; }
從證明可以看出,歐拉函數是非完全積性函數
所以可以用線性篩來O(n) 預處理值
bool check[maxn]; int phi[maxn]; int prime[maxn]; int tot;//素數的個數 void phi_and_prime_table(int n) { memset(check,false,sizeof(check)); phi[1] = 1; tot = 0; for(int i = 2; i <= n; i++) { if( !check[i] ) { prime[tot++] = i; phi[i] = i-1; } for(int j = 0; j < tot; j++) { if(i * prime[j] > n)break; check[i * prime[j]] = true; if( i % prime[j] == 0) { phi[i * prime[j]] = phi[i] * prime[j]; break; } else { phi[i * prime[j]] = phi[i] * (prime[j] - 1); } } } }
性質:

考慮gcd,假設i與n的gcd為g,那么有g|n , gcd(n/g,i/g)=1
