Number Theory & Algebra contents
Euler's Totient Function
Count the integers up to n that are coprime to n, compute φ(n) from the factorization or for all n at once, and apply Euler's theorem.
Read first: Integer Factorization
Euler's totient function counts the integers in that are coprime to :
The first values are:
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 1 | 2 | 2 | 4 | 2 | 6 | 4 | 6 | 4 |
Properties
- For a prime : , since every smaller positive number is coprime to it.
- For a prime power: , because only the multiples of are not coprime, and there are of them.
- Multiplicative: if then .
Combining these gives the formula from the prime factorization :
For example .
Computing for one number,
Factor by trial division and apply for each distinct prime :
def phi(n):
result = n
p = 2
while p * p <= n:
if n % p == 0:
while n % p == 0:
n //= p
result -= result // p # multiply by (1 - 1/p) exactly
p += 1
if n > 1: # one prime factor larger than sqrt(n) remains
result -= result // n
return result
from math import gcd
assert [phi(n) for n in range(1, 11)] == [1, 1, 2, 2, 4, 2, 6, 4, 6, 4]
assert phi(36) == 12 and phi(10 ** 9 + 7) == 10 ** 9 + 6
assert all(phi(n) == sum(1 for k in range(1, n + 1) if gcd(k, n) == 1) for n in range(1, 300))result -= result // p is the integer version of result *= (1 - 1/p); it is exact because result is still divisible by p.
The totient of all numbers up to in
Sieve-style: start with and, for every prime , apply the factor to all multiples of .
def phi_sieve(n):
phi = list(range(n + 1))
for i in range(2, n + 1):
if phi[i] == i: # untouched so far: i is prime
for j in range(i, n + 1, i):
phi[j] -= phi[j] // i
return phi
table = phi_sieve(1000)
assert table[:11] == [0, 1, 1, 2, 2, 4, 2, 6, 4, 6, 4]
assert all(table[i] == phi(i) for i in range(1, 1001))Divisor sum property
Summing over the divisors of gives back :
Intuitively, sort the fractions for by their reduced denominator ; there are exactly fractions with denominator .
for n in range(1, 400):
assert sum(phi(d) for d in range(1, n + 1) if n % d == 0) == nThe property yields another way to build all values, with , in .
Euler's theorem
If then
For a prime modulus this is Fermat's little theorem, . Two consequences that appear constantly:
- Modular inverse: (see Modular Inverse).
- Huge exponents: when .
m, a = 1000, 7 # gcd(7, 1000) = 1
assert pow(a, phi(m), m) == 1
huge = 10 ** 100 + 12345
assert pow(a, huge, m) == pow(a, huge % phi(m), m) # reduce the exponent firstCounting
Because counts numbers coprime to , it counts the reduced fractions with denominator in ; the number of reduced fractions with denominator at most is (the length of the Farey sequence).
N = 30
farey = {(a // gcd(a, b), b // gcd(a, b)) for b in range(1, N + 1) for a in range(1, b + 1)}
assert len(farey) == sum(phi_sieve(N)[1:])Practice problems
- 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