Open In App

Count numbers up to N whose GCD with N is less than that number

Last Updated : 01 Feb, 2023
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an integer N, the task is to count the values of K ( where 1 ? K? N ), such that 1< GCD(K, N) < K.

Examples:

Input: N = 10
Output: 3
Explanation: The values of K which satisfies the given conditions are: 

  • K = 4, gcd(4, 10) = 2
  • K = 6, gcd(6, 10) = 2
  • K = 8, gcd(8, 10) = 2

Input: N = 15
Output: 4
Explanation: The values of K which satisfies the given conditions are: 

  • K = 6, gcd(6, 15) = 3
  • K = 9, gcd(9, 15) = 3
  • K = 10, gcd(10, 15) = 5
  • K = 12, gcd(12, 15) = 3

Naive Approach: The simplest approach is to iterate over the range [1, N], and check for each number, whether it satisfies the given condition or not. Finally, print the count of such numbers.

Time Complexity: O(N*log(N))
Auxiliary Space: O(1) 

Efficient Approach: The idea is to find all the numbers in the range [1, N], for which gcd(K, N) = 1 and gcd(K, N) = K and then finally remove all these numbers from N to get the final answer. Follow the steps below to solve the problem:

  • Store all the prime factors of N using Sieve of Eratosthenes.
  • Store the count of all the numbers in the range [1, N] for which gcd(N, K) = K in a variable count1.
  • Store the count of all the numbers in the range [1, N] for which gcd(N, K) = 1 using Euler's Totient Function in a variable count2.
  • Remove these numbers from N, by updating ans to N - (count1 + count2).
  • Print the value of ans as the result.

Below is the implementation of the above approach:

C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;

// Store the all prime numbers
// using Sieve of Eratosthenes
const int MAXN = 100001;
vector<int> spf;

// Function to fill the prime numbers
// using Sieve of Eratosthenes
void sieve()
{
    // Create a boolean array and
    // initialize all entries it as 0
    int p[MAXN + 1] = { 0 };

    p[2] = 1;
    for (long long int i = 3; i < MAXN; i += 2) {
        p[i] = 1;
    }

    // Push the first prime number
    spf.push_back(2);

    for (long long i = 3; i < MAXN; i += 2) {

        // If the current number is prime
        if (p[i]) {

            // Store the prime numbers
            // in spf which is prime
            spf.push_back(i);

            // Mark all its multiples as false
            for (long long int j = i * i; j < MAXN;
                 j += 2 * i)
                p[j] = 0;
        }
    }
}

// Function to count the values of K where
// 1?K?N such that 1< gcd(K, N) < K
void countK(int N)
{
    // Precalculate prime numbers
    sieve();
    int N1 = N;

    // Store the smallest prime number
    int div = spf[0];

    int index = 1, C = 0;

    // Store the count of those numbers in the
    // range [1, N] for which gcd(N, K) = K
    int count1 = 1;

    // Store the count of those numbers from
    // the range [1, N] such that gcd(N, K) = 1
    float count2 = N;

    // Iterate through all prime factors of N
    while (div * div <= N) {
        if (N % div == 0) {
            C = 0;
            while (N % div == 0) {
                N /= div;
                C++;
            }

            count1 = count1 * (C + 1);

            // count2 is determined by
            // Euler's Totient Function
            count2 *= (1.0 - (1.0 / (float)div));
        }

        div = spf[index];

        index++;
    }
    if (N != 1) {

        count1 *= 2;
        count2 = count2 * (1.0 - (1.0 / (float)N));
    }

    int ans = N1 - count1 - count2;

    // Add 1 to result as 1 is contributed
    // twice due to count1 and count2
    ans = ans + 1;

    // Print the result
    cout << ans;

    return;
}

// Driver Code
int main()
{
    // Given Input
    int N = 10;

    // Function Call
    countK(N);

    return 0;
}
Java
// Java code to implement the approach
import java.util.ArrayList;

class GFG {

    // Store the all prime numbers
    // using Sieve of Eratosthenes
    private static final int MAXN = 100001;
    private static ArrayList<Integer> spf
        = new ArrayList<>();

    // Function to fill the prime numbers
    // using Sieve of Eratosthenes
    private static void sieve()
    {
        // Create a boolean array and
        // initialize all entries it as 0
        int[] p = new int[MAXN + 1];

        p[2] = 1;
        for (long i = 3; i < MAXN; i += 2) {
            p[(int)i] = 1;
        }

        // Push the first prime number
        spf.add(2);

        for (long i = 3; i < MAXN; i += 2) {
            // If the current number is prime
            if (p[(int)i] == 1) {
                // Store the prime numbers
                // in spf which is prime
                spf.add((int)i);

                // Mark all its multiples as false
                for (long j = i * i; j < MAXN; j += 2 * i)
                    p[(int)j] = 0;
            }
        }
    }

    // Function to count the values of K where
    // 1 <= K <= N such that 1< gcd(K, N) < K
    private static void countK(int N)
    {
        // Precalculate prime numbers
        sieve();
        int N1 = N;
        // Store the smallest prime number
        int div = spf.get(0);

        int index = 1, C = 0;

        // Store the count of those numbers in the
        // range [1, N] for which gcd(N, K) = K
        int count1 = 1;

        // Store the count of those numbers from
        // the range [1, N] such that gcd(N, K) = 1
        double count2 = N;

        // Iterate through all prime factors of N
        while (div * div <= N) {
            if (N % div == 0) {
                C = 0;
                while (N % div == 0) {
                    N /= div;
                    C++;
                }

                count1 = count1 * (C + 1);

                // count2 is determined by
                // Euler's Totient Function
                count2 *= (1.0 - (1.0 / (double)div));
            }

            div = spf.get(index);

            index++;
        }
        if (N != 1) {
            count1 *= 2;
            count2 = count2 * (1.0 - (1.0 / (double)N));
        }

        int ans = N1 - count1 - (int)count2;

        // Add 1 to result as 1 is contributed
        // twice due to count1 and count2
        ans = ans + 1;

        // Print the result
        System.out.println(ans);

        return;
    }

    // Driver Code
    public static void main(String[] args)
    {
        int N = 10;

        // Function call
        countK(N);
    }
}


// This code is contributed by phasing17
Python3
# Python3 program for the above approach

# Store the all prime numbers
# using Sieve of Eratosthenes
MAXN = 100001
spf = []

# Function to fill the prime numbers
# using Sieve of Eratosthenes
def sieve():
    
    global MAXN
    
    # Create a boolean array and
    # initialize all entries it as 0
    p = [0] * (MAXN + 1)
    p[2] = 1
    
    for i in range(3, MAXN, 2):
        p[i] = 1

    # Push the first prime number
    spf.append(2)

    for i in range(3, MAXN, 2):
        
        # If the current number is prime
        if (p[i]):

            # Store the prime numbers
            # in spf which is prime
            spf.append(i)

            # Mark all its multiples as false
            for j in range(i * i, MAXN, 2 * i):
                p[j] = 0

# Function to count the values of K where
# 1?K?N such that 1< gcd(K, N) < K
def countK(N):
    
    # Precalculate prime numbers
    sieve()
    N1 = N

    # Store the smallest prime number
    div = spf[0]

    index, C = 1, 0

    # Store the count of those numbers in the
    # range [1, N] for which gcd(N, K) = K
    count1 = 1

    # Store the count of those numbers from
    # the range [1, N] such that gcd(N, K) = 1
    count2 = N

    # Iterate through all prime factors of N
    while (div * div <= N):
        if (N % div == 0):
            C = 0
            
            while (N % div == 0):
                N //= div
                C += 1

            count1 = count1 * (C + 1)

            # count2 is determined by
            # Euler's Totient Function
            count2 *= (1.0 - (1.0 / div))

        div = spf[index]

        index += 1

    if (N != 1):
        count1 *= 2
        count2 = count2 * (1.0 - (1.0 / N))

    ans = N1 - count1 - count2

    # Add 1 to result as 1 is contributed
    # twice due to count1 and count2
    ans = ans + 1

    # Print the result
    print(int(ans))

# Driver Code
if __name__ == '__main__':
    
    # Given Input
    N = 10

    # Function Call
    countK(N)

# This code is contributed by mohit kumar 29
C#
// C# code to implement the approach
using System;
using System.Collections.Generic;

class GFG
{
  
  // Store the all prime numbers
  // using Sieve of Eratosthenes
  private const int MAXN = 100001;
  private static List<int> spf = new List<int>();

  // Function to fill the prime numbers
  // using Sieve of Eratosthenes
  private static void sieve()
  {
    
    // Create a boolean array and
    // initialize all entries it as 0
    int[] p = new int[MAXN + 1];

    p[2] = 1;
    for (long i = 3; i < MAXN; i += 2) {
      p[i] = 1;
    }

    // Push the first prime number
    spf.Add(2);

    for (long i = 3; i < MAXN; i += 2) {
      // If the current number is prime
      if (p[i] == 1) {
        // Store the prime numbers
        // in spf which is prime
        spf.Add((int)i);

        // Mark all its multiples as false
        for (long j = i * i; j < MAXN; j += 2 * i)
          p[j] = 0;
      }
    }
  }

  // Function to count the values of K where
  // 1?K?N such that 1< gcd(K, N) < K
  private static void countK(int N)
  {
    // Precalculate prime numbers
    sieve();
    int N1 = N;

    // Store the smallest prime number
    int div = spf[0];

    int index = 1, C = 0;

    // Store the count of those numbers in the
    // range [1, N] for which gcd(N, K) = K
    int count1 = 1;

    // Store the count of those numbers from
    // the range [1, N] such that gcd(N, K) = 1
    double count2 = N;

    // Iterate through all prime factors of N
    while (div * div <= N) {
      if (N % div == 0) {
        C = 0;
        while (N % div == 0) {
          N /= div;
          C++;
        }

        count1 = count1 * (C + 1);

        // count2 is determined by
        // Euler's Totient Function
        count2 *= (1.0 - (1.0 / (double)div));
      }

      div = spf[index];

      index++;
    }
    if (N != 1) {
      count1 *= 2;
      count2 = count2 * (1.0 - (1.0 / (double)N));
    }

    int ans = N1 - count1 - (int)count2;

    // Add 1 to result as 1 is contributed
    // twice due to count1 and count2
    ans = ans + 1;

    // Print the result
    Console.WriteLine(ans);

    return;
  }

  // Driver Code
  static void Main(string[] args)
  {
    int N = 10;

    // Function call
    countK(N);
  }
}

// This code is contributed by phasing17
JavaScript
<script>

// Javascript program for the above approach

// Store the all prime numbers
// using Sieve of Eratosthenes
var MAXN = 100001;
var spf = [];

// Function to fill the prime numbers
// using Sieve of Eratosthenes
function sieve()
{

// Create a boolean array and
    // initialize all entries it as 0
    var p = Array(MAXN + 1).fill(0);

    p[2] = 1;
    for (var i = 3; i < MAXN; i += 2) {
        p[i] = 1;
    }

    // Push the first prime number
    spf.push(2);

    for (var i = 3; i < MAXN; i += 2) {

        // If the current number is prime
        if (p[i]) {

            // Store the prime numbers
            // in spf which is prime
            spf.push(i);

            // Mark all its multiples as false
            for (var j = i * i; j < MAXN;
                 j += 2 * i)
                p[j] = 0;
        }
    }
}

// Function to count the values of K where
// 1?K?N such that 1< gcd(K, N) < K
function countK(N)
{
    // Precalculate prime numbers
    sieve();
    var N1 = N;

    // Store the smallest prime number
    var div = spf[0];

    var index = 1, C = 0;

    // Store the count of those numbers in the
    // range [1, N] for which gcd(N, K) = K
    var count1 = 1;

    // Store the count of those numbers from
    // the range [1, N] such that gcd(N, K) = 1
    var count2 = N;

    // Iterate through all prime factors of N
    while (div * div <= N) {
        if (N % div == 0) {
            C = 0;
            while (N % div == 0) {
                N /= div;
                C++;
            }

            count1 = count1 * (C + 1);

            // count2 is determined by
            // Euler's Totient Function
            count2 *= (1.0 - (1.0 / div));
        }

        div = spf[index];

        index++;
    }
    if (N != 1) {

        count1 *= 2;
        count2 = count2 * (1.0 - (1.0 / N));
    }

    var ans = N1 - count1 - count2;

    // Add 1 to result as 1 is contributed
    // twice due to count1 and count2
    ans = ans + 1;

    // Print the result
    document.write(ans);

    return;
}

// Driver Code
// Given Input
var N = 10;

// Function Call
countK(N);

// This code is contributed by rutvik_56.
</script>

Output: 
3

 

Time Complexity: O(N*log(log(N)))
 Auxiliary Space: O(N) 


Next Article
Practice Tags :

Similar Reads