| tags |
|
|
|---|---|---|
| e_maxx_link | euler_function |
Euler's totient function, also known as phi-function
Here are values of
The following properties of Euler totient function are sufficient to calculate it for any number:
- If
$p$ is a prime number, then$\gcd(p, q) = 1$ for all$1 \le q < p$ . Therefore we have:
- If
$p$ is a prime number and$k \ge 1$ , then there are exactly$p^k / p$ numbers between$1$ and$p^k$ that are divisible by$p$ . Which gives us:
-
If
$a$ and$b$ are relatively prime, then:[\phi(a b) = \phi(a) \cdot \phi(b).]
This relation is not trivial to see. It follows from the Chinese remainder theorem. The Chinese remainder theorem guarantees, that for each
$0 \le x < a$ and each$0 \le y < b$ , there exists a unique$0 \le z < a b$ with$z \equiv x \pmod{a}$ and$z \equiv y \pmod{b}$ . It's not hard to show that$z$ is coprime to$a b$ if and only if$x$ is coprime to$a$ and$y$ is coprime to$b$ . Therefore the amount of integers coprime to$a b$ is equal to product of the amounts of$a$ and$b$ . -
In general, for not coprime
$a$ and$b$ , the equation[\phi(ab) = \phi(a) \cdot \phi(b) \cdot \dfrac{d}{\phi(d)}]
with
$d = \gcd(a, b)$ holds.
Thus, using the first three properties, we can compute
Here is an implementation using factorization in
int phi(int n) {
int result = n;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
while (n % i == 0)
n /= i;
result -= result / i;
}
}
if (n > 1)
result -= result / n;
return result;
}Euler totient function from $1$ to $n$ in $O(n \log\log{n})$ { #etf_1_to_n data-toc-label="Euler totient function from 1 to n in <script type="math/tex">O(n log log n)</script>" }
If we need the totient of all numbers between
Since this approach is basically identical to the Sieve of Eratosthenes, the complexity will also be the same:
void phi_1_to_n(int n) {
vector<int> phi(n + 1);
for (int i = 0; i <= n; i++)
phi[i] = i;
for (int i = 2; i <= n; i++) {
if (phi[i] == i) {
for (int j = i; j <= n; j += i)
phi[j] -= phi[j] / i;
}
}
}Finding the totient from $L$ to $R$ using the segmented sieve { data-toc-label="Finding the totient from L to R using the segmented sieve" }
If we need the totient of all numbers between
The algorithm first precomputes all primes up to
const long long MAX_RANGE = 1e6 + 6;
vector<long long> primes;
long long phi[MAX_RANGE], rem[MAX_RANGE];
vector<int> linear_sieve(int n) {
vector<bool> composite(n + 1, 0);
vector<int> prime;
// 0 and 1 are not composite (nor prime)
composite[0] = composite[1] = 1;
for(int i = 2; i <= n; i++) {
if(!composite[i]) prime.push_back(i);
for(int j = 0; j < prime.size() && i * prime[j] <= n; j++) {
composite[i * prime[j]] = true;
if(i % prime[j] == 0) break;
}
}
return prime;
}
// To get the value of phi(x) for L <= x <= R, use phi[x - L].
void segmented_phi(long long L, long long R) {
for(long long i = L; i <= R; i++) {
rem[i - L] = i;
phi[i - L] = i;
}
for(long long i : primes) {
for(long long j = max(i * i, (L + i - 1) / i * i); j <= R; j += i) {
phi[j - L] -= phi[j - L] / i;
while(rem[j - L] % i == 0) rem[j - L] /= i;
}
}
for(long long i = 0; i < R - L + 1; i++) {
if(rem[i] > 1) phi[i] -= phi[i] / rem[i];
}
}This interesting property was established by Gauss:
Here the sum is over all positive divisors
For instance the divisors of 10 are 1, 2, 5 and 10.
Hence
Finding the totient from 1 to $n$ using the divisor sum property { data-toc-label="Finding the totient from 1 to n using the divisor sum property" }
The divisor sum property also allows us to compute the totient of all numbers between 1 and
void phi_1_to_n(int n) {
vector<int> phi(n + 1);
phi[0] = 0;
phi[1] = 1;
for (int i = 2; i <= n; i++)
phi[i] = i - 1;
for (int i = 2; i <= n; i++)
for (int j = 2 * i; j <= n; j += i)
phi[j] -= phi[i];
}The most famous and important property of Euler's totient function is expressed in Euler's theorem:
In the particular case when
Euler's theorem and Euler's totient function occur quite often in practical applications, for example both are used to compute the modular multiplicative inverse.
As immediate consequence we also get the equivalence:
This allows computing
The multiplicative order of an element
There is a less known version of the last equivalence, that allows computing
Proof:
Let
The equivalence between the third and forth line follows from the fact that
Since
This formula is difficult to apply, but we can use it to analyze the behavior of
- SPOJ #4141 "Euler Totient Function" [Difficulty: CakeWalk]
- UVA #10179 "Irreducible Basic Fractions" [Difficulty: Easy]
- UVA #10299 "Relatives" [Difficulty: Easy]
- UVA #11327 "Enumerating Rational Numbers" [Difficulty: Medium]
- TIMUS #1673 "Admission to Exam" [Difficulty: High]
- UVA 10990 - Another New Function
- Codechef - Golu and Sweetness
- SPOJ - LCM Sum
- GYM - Simple Calculations (F)
- UVA 13132 - Laser Mirrors
- SPOJ - GCDEX
- UVA 12995 - Farey Sequence
- SPOJ - Totient in Permutation (easy)
- LOJ - Mathematically Hard
- SPOJ - Totient Extreme
- SPOJ - Playing with GCD
- SPOJ - G Force
- SPOJ - Smallest Inverse Euler Totient Function
- Codeforces - Power Tower
- Kattis - Exponial
- LeetCode - 372. Super Pow
- Codeforces - The Holmes Children
- Codeforces - Small GCD