Open In App

Optimized Euler Totient Function for Multiple Evaluations

Improve
Improve
Like Article
Like
Save
Share
Report

Euler Totient Function (ETF) ?(n) for an input n is count of numbers in {1, 2, 3, …, n} that are relatively prime to n, i.e., the numbers whose GCD (Greatest Common Divisor) with n is 1. 
Examples: 
 

?(5) = 4
gcd(1, 5) is 1, gcd(2, 5) is 1, 
gcd(3, 5) is 1 and gcd(4, 5) is 1

?(6) = 2
gcd(1, 6) is 1 and gcd(5, 6) is 1,

 

Recommended Practice

We have discussed different methods to compute Euler Totient function that work well for single input. In problems where we have to call Euler’s Totient Function many times like 10^5 times, simple solution will result in TLE(Time limit Exceeded). The idea is to use Sieve of Eratosthenes.
Find all prime numbers upto maximum limit say 10^5 using Sieve of Eratosthenes
To compute ?(n), we do following. 
 

  1. Initialize result as n.
  2. Iterate through all primes smaller than or equal to square root of n (This is where it is different from simple methods. Instead of iterating through all numbers less than or equal to square root, we iterate through only primes). Let the current prime number be p. We check if p divides n, if yes, we remove all occurrences of p from n by repeatedly dividing it with n. We also reduce our result by n/p (these many numbers will not have GCD as 1 with n).
  3. Finally we return result.

 

C++




// C++ program to efficiently compute values
// of euler totient function for multiple inputs.
#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
const int MAX = 100001;
 
// Stores prime numbers upto MAX - 1 values
vector<ll> p;
 
// Finds prime numbers upto MAX-1 and
// stores them in vector p
void sieve()
{
    ll isPrime[MAX+1];
 
    for (ll i = 2; i<= MAX; i++)
    {
        // if prime[i] is not marked before
        if (isPrime[i] == 0)
        {
            // fill vector for every newly
            // encountered prime
            p.push_back(i);
 
            // run this loop till square root of MAX,
            // mark the index i * j as not prime
            for (ll j = 2; i * j<= MAX; j++)
                isPrime[i * j]= 1;
        }
    }
}
 
// function to find totient of n
ll phi(ll n)
{
    ll res = n;
 
    // this loop runs sqrt(n / ln(n)) times
    for (ll i=0; p[i]*p[i] <= n; i++)
    {
        if (n % p[i]== 0)
        {
            // subtract multiples of p[i] from r
            res -= (res / p[i]);
 
            // Remove all occurrences of p[i] in n
            while (n % p[i]== 0)
               n /= p[i];
        }
    }
 
    // when n has prime factor greater
    // than sqrt(n)
    if (n > 1)
       res -= (res / n);
 
    return res;
}
 
// Driver code
int main()
{
    // preprocess all prime numbers upto 10 ^ 5
    sieve();
    cout << phi(11) << "\n";
    cout << phi(21) << "\n";
    cout << phi(31) << "\n";
    cout << phi(41) << "\n";
    cout << phi(51) << "\n";
    cout << phi(61) << "\n";
    cout << phi(91) << "\n";
    cout << phi(101) << "\n";
    return 0;
}


Java




// Java program to efficiently compute values
// of euler totient function for multiple inputs.
import java.util.*;
 
class GFG{
static int MAX = 100001;
 
// Stores prime numbers upto MAX - 1 values
static ArrayList<Integer> p = new ArrayList<Integer>();
 
// Finds prime numbers upto MAX-1 and
// stores them in vector p
static void sieve()
{
    int[] isPrime=new int[MAX+1];
 
    for (int i = 2; i<= MAX; i++)
    {
        // if prime[i] is not marked before
        if (isPrime[i] == 0)
        {
            // fill vector for every newly
            // encountered prime
            p.add(i);
 
            // run this loop till square root of MAX,
            // mark the index i * j as not prime
            for (int j = 2; i * j<= MAX; j++)
                isPrime[i * j]= 1;
        }
    }
}
 
// function to find totient of n
static int phi(int n)
{
    int res = n;
 
    // this loop runs sqrt(n / ln(n)) times
    for (int i=0; p.get(i)*p.get(i) <= n; i++)
    {
        if (n % p.get(i)== 0)
        {
            // subtract multiples of p[i] from r
            res -= (res / p.get(i));
 
            // Remove all occurrences of p[i] in n
            while (n % p.get(i)== 0)
            n /= p.get(i);
        }
    }
 
    // when n has prime factor greater
    // than sqrt(n)
    if (n > 1)
    res -= (res / n);
 
    return res;
}
 
// Driver code
public static void main(String[] args)
{
    // preprocess all prime numbers upto 10 ^ 5
    sieve();
    System.out.println(phi(11));
    System.out.println(phi(21));
    System.out.println(phi(31));
    System.out.println(phi(41));
    System.out.println(phi(51));
    System.out.println(phi(61));
    System.out.println(phi(91));
    System.out.println(phi(101));
  
}
}
// this code is contributed by mits


Python3




# Python3 program to efficiently compute values
# of euler totient function for multiple inputs.
 
MAX = 100001;
 
# Stores prime numbers upto MAX - 1 values
p = [];
 
# Finds prime numbers upto MAX-1 and
# stores them in vector p
def sieve():
 
    isPrime = [0] * (MAX + 1);
 
    for i in range(2, MAX + 1):
         
        # if prime[i] is not marked before
        if (isPrime[i] == 0):
             
            # fill vector for every newly
            # encountered prime
            p.append(i);
 
            # run this loop till square root of MAX,
            # mark the index i * j as not prime
            j = 2;
            while (i * j <= MAX):
                isPrime[i * j]= 1;
                j += 1;
 
# function to find totient of n
def phi(n):
 
    res = n;
 
    # this loop runs sqrt(n / ln(n)) times
    i = 0;
    while (p[i] * p[i] <= n):
        if (n % p[i]== 0):
             
            # subtract multiples of p[i] from r
            res -= int(res / p[i]);
 
            # Remove all occurrences of p[i] in n
            while (n % p[i]== 0):
                n = int(n / p[i]);
        i += 1;
 
    # when n has prime factor greater
    # than sqrt(n)
    if (n > 1):
        res -= int(res / n);
 
    return res;
 
# Driver code
 
# preprocess all prime numbers upto 10 ^ 5
sieve();
print(phi(11));
print(phi(21));
print(phi(31));
print(phi(41));
print(phi(51));
print(phi(61));
print(phi(91));
print(phi(101));
 
# This code is contributed by mits


C#




// C# program to efficiently compute values
// of euler totient function for multiple inputs.
using System;
using System.Collections;
class GFG{
static int MAX = 100001;
 
// Stores prime numbers upto MAX - 1 values
static ArrayList p = new ArrayList();
 
// Finds prime numbers upto MAX-1 and
// stores them in vector p
static void sieve()
{
    int[] isPrime=new int[MAX+1];
 
    for (int i = 2; i<= MAX; i++)
    {
        // if prime[i] is not marked before
        if (isPrime[i] == 0)
        {
            // fill vector for every newly
            // encountered prime
            p.Add(i);
 
            // run this loop till square root of MAX,
            // mark the index i * j as not prime
            for (int j = 2; i * j<= MAX; j++)
                isPrime[i * j]= 1;
        }
    }
}
 
// function to find totient of n
static int phi(int n)
{
    int res = n;
 
    // this loop runs sqrt(n / ln(n)) times
    for (int i=0; (int)p[i]*(int)p[i] <= n; i++)
    {
        if (n % (int)p[i]== 0)
        {
            // subtract multiples of p[i] from r
            res -= (res / (int)p[i]);
 
            // Remove all occurrences of p[i] in n
            while (n % (int)p[i]== 0)
            n /= (int)p[i];
        }
    }
 
    // when n has prime factor greater
    // than sqrt(n)
    if (n > 1)
    res -= (res / n);
 
    return res;
}
 
// Driver code
static void Main()
{
    // preprocess all prime numbers upto 10 ^ 5
    sieve();
    Console.WriteLine(phi(11));
    Console.WriteLine(phi(21));
    Console.WriteLine(phi(31));
    Console.WriteLine(phi(41));
    Console.WriteLine(phi(51));
    Console.WriteLine(phi(61));
    Console.WriteLine(phi(91));
    Console.WriteLine(phi(101));
 
}
}
// this code is contributed by mits


PHP




<?php
// PHP program to efficiently compute values
// of euler totient function for multiple inputs.
 
$MAX = 100001;
 
// Stores prime numbers upto MAX - 1 values
$p = array();
 
// Finds prime numbers upto MAX-1 and
// stores them in vector p
function sieve()
{
    global $MAX,$p;
    $isPrime=array_fill(0,$MAX+1,0);
 
    for ($i = 2; $i<= $MAX; $i++)
    {
        // if prime[i] is not marked before
        if ($isPrime[$i] == 0)
        {
            // fill vector for every newly
            // encountered prime
            array_push($p,$i);
 
            // run this loop till square root of MAX,
            // mark the index i * j as not prime
            for ($j = 2; $i * $j<= $MAX; $j++)
                $isPrime[$i * $j]= 1;
        }
    }
}
 
// function to find totient of n
function phi($n)
{
    global $p;
    $res = $n;
 
    // this loop runs sqrt(n / ln(n)) times
    for ($i=0; $p[$i]*$p[$i] <= $n; $i++)
    {
        if ($n % $p[$i]== 0)
        {
            // subtract multiples of p[i] from r
            $res -= (int)($res / $p[$i]);
 
            // Remove all occurrences of p[i] in n
            while ($n % $p[$i]== 0)
            $n = (int)($n/$p[$i]);
        }
    }
 
    // when n has prime factor greater
    // than sqrt(n)
    if ($n > 1)
    $res -= (int)($res / $n);
 
    return $res;
}
 
// Driver code
  
    // preprocess all prime numbers upto 10 ^ 5
    sieve();
    print(phi(11)."\n");
    print(phi(21)."\n");
    print(phi(31)."\n");
    print(phi(41)."\n");
    print(phi(51)."\n");
    print(phi(61)."\n");
    print(phi(91)."\n");
    print(phi(101)."\n");
 
// this code is contributed by mits
?>


Javascript




<script>
 
// Javascript program to efficiently compute values
// of euler totient function for multiple inputs.
 
var MAX = 100001;
 
// Stores prime numbers upto MAX - 1 values
var p = [];
 
// Finds prime numbers upto MAX-1 and
// stores them in vector p
function sieve()
{
    var isPrime = Array(MAX+1).fill(0);
 
    for (var i = 2; i<= MAX; i++)
    {
        // if prime[i] is not marked before
        if (isPrime[i] == 0)
        {
            // fill vector for every newly
            // encountered prime
            p.push(i);
 
            // run this loop till square root of MAX,
            // mark the index i * j as not prime
            for (var j = 2; i * j<= MAX; j++)
                isPrime[i * j]= 1;
        }
    }
}
 
// function to find totient of n
function phi(n)
{
    var res = n;
 
    // this loop runs sqrt(n / ln(n)) times
    for (var i=0; p[i]*p[i] <= n; i++)
    {
        if (n % p[i]== 0)
        {
            // subtract multiples of p[i] from r
            res -= parseInt(res / p[i]);
 
            // Remove all occurrences of p[i] in n
            while (n % p[i]== 0)
            n = parseInt(n/p[i]);
        }
    }
 
    // when n has prime factor greater
    // than sqrt(n)
    if (n > 1)
    res -= parseInt(res / n);
 
    return res;
}
 
// Driver code
// preprocess all prime numbers upto 10 ^ 5
sieve();
document.write(phi(11)+ "<br>");
document.write(phi(21)+ "<br>");
document.write(phi(31)+ "<br>");
document.write(phi(41)+ "<br>");
document.write(phi(51)+ "<br>");
document.write(phi(61)+ "<br>");
document.write(phi(91)+ "<br>");
document.write(phi(101)+ "<br>");
 
// This code is contributed by rutvik_56.
</script>


Output: 
 

10
12
30
40
32
60
72
100

Time Complexity: O(MAX*log(MAX)+sqrt(n/log(n)))

Auxiliary Space: O(MAX)

 



Last Updated : 17 Sep, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads