Count of natural numbers in range [L, R] which are relatively prime with N

Given three integers N, L, and R. The task is to calculate the number of natural numbers in the range [L, R] (both inclusive) which are relatively prime with N.

Examples:

Input: N = 10, L = 1, R = 25
Output: 10
Explanation:
10 natural numbers (in the range 1 to 25) are relatively prime to 10.
They are 1, 3, 7, 9, 11, 13, 17, 19, 21, 23.

Input: N = 12, L = 7, R = 38
Output: 11
Explanation:
11 natural numbers (in the range 1 to 38) are relatively prime to 12.
They are 7, 11, 13, 17, 19, 23, 25, 29, 31, 35, 37.

Approach:



  1. At first, factorize the number N. Thus, find out all the prime factors of N.
  2. Store prime factors of the number N in an array.
  3. We can determine the total number of natural numbers which are not greater than R and are divisible by prime factors of N.
  4. Suppose that the value is y. So, exactly y natural numbers not greater than R have at least a single common divisor with N.
  5. So, these y numbers can not be relatively prime to N.
  6. Thus, the number of natural number not greater than R which are relatively prime to N will be R – y .
  7. Now, similarly we need to find out the number of relatively prime numbers of N which are not greater than L-1.
  8. Then, subtract the result for L-1 from the answer for R.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ code to count of natural
// numbers in range [L, R] which
// are relatively prime with N
  
#include <bits/stdc++.h>
using namespace std;
#define maxN (long long)1000000000000
  
// container of all the primes
// up to sqrt(n)
vector<int> prime;
  
// Function to calculate prime
// factors of n
void sieve(long long n)
{
    // run the sieve of Eratosthenes
    bool check[1000007] = { 0 };
    long long i, j;
  
    // 0(false) means prime,
    // 1(true) means not prime
    check[0] = 1, check[1] = 1,
    check[2] = 0;
  
    // no even number is
    // prime except for 2
    for (i = 4; i <= n; i += 2)
        check[i] = true;
  
    for (i = 3; i * i <= n; i += 2)
        if (!check[i]) {
  
            // all the multiples of each
            // each prime numbers are
            // non-prime
            for (j = i * i; j <= n; j += 2 * i)
                check[j] = true;
        }
  
    prime.push_back(2);
  
    // get all the primes
    // in prime vector
    for (int i = 3; i <= n; i += 2)
        if (!check[i])
            prime.push_back(i);
  
    return;
}
  
// Count the number of numbers
// up to m which are divisible
// by given prime numbers
long long count(long long a[],
                int n, long long m)
{
    long long parity[3] = { 0 };
  
    // Run from i= 000..0 to i= 111..1
    // or check all possible
    // subsets of the array
    for (int i = 1; i < (1 << n); i++) {
        long long mult = 1;
        for (int j = 0; j < n; j++)
            if (i & (1 << j))
                mult *= a[j];
  
        // take the multiplication
        // of all the set bits
  
        // if the number of set bits
        // is odd, then add to the
        // number of multiples
        parity[__builtin_popcount(i) & 1]
            += (m / mult);
    }
  
    return parity[1] - parity[0];
}
  
// Function calculates all number
// not greater than 'm' which are
// relatively prime with n.
long long countRelPrime(
    long long n,
    long long m)
{
  
    long long a[20];
    int i = 0, j = 0;
    long long pz = prime.size();
    while (n != 1 && i < pz) {
  
        // if square of the prime number
        // is greater than 'n', it can't
        // be a factor of 'n'
        if ((long long)prime[i]
                * (long long)prime[i]
            > n)
            break;
  
        // if prime is a factor of
        // n then increment count
        if (n % prime[i] == 0)
            a[j] = (long long)prime[i], j++;
  
        while (n % prime[i] == 0)
            n /= prime[i];
        i++;
    }
  
    if (n != 1)
        a[j] = n, j++;
    return m - count(a, j, m);
}
  
void countRelPrimeInRange(
    long long n, long long l,
    long long r)
{
    sieve(sqrt(maxN));
    long long result
        = countRelPrime(n, r)
          - countRelPrime(n, l - 1);
    cout << result << "\n";
}
  
// Driver code
int main()
{
    long long N = 7, L = 3, R = 9;
    countRelPrimeInRange(N, L, R);
  
    return 0;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 code to count of natural
# numbers in range [L, R] which
# are relatively prime with N
from math import sqrt, floor
  
maxN = 1000000000000
  
# Container of all the primes
# up to sqrt(n)
prime = []
  
# Function to calculate prime
# factors of n
def sieve(n):
      
    # Run the sieve of Eratosthenes
    check = [0] * (1000007)
    i, j = 0, 0
  
    # 0(false) means prime,
    # 1(True) means not prime
    check[0] = 1
    check[1] = 1
    check[2] = 0
  
    # No even number is
    # prime except for 2
    for i in range(4, n + 1, 2):
        check[i] = True
  
    for i in range(3, n + 1, 2):
        if i * i > n:
            break
        if (not check[i]):
  
            # All the multiples of each
            # each prime numbers are
            # non-prime
            for j in range(2 * i, n + 1, 2 * i):
                check[j] = True
  
    prime.append(2)
  
    # Get all the primes
    # in prime vector
    for i in range(3, n + 1, 2):
        if (not check[i]):
            prime.append(i)
  
    return
  
# Count the number of numbers
# up to m which are divisible
# by given prime numbers
def count(a, n, m):
      
    parity = [0] * 3
  
    # Run from i= 000..0 to i= 111..1
    # or check all possible
    # subsets of the array
    for i in range(1, 1 << n):
        mult = 1
        for j in range(n):
            if (i & (1 << j)):
                mult *= a[j]
  
        # Take the multiplication
        # of all the set bits
  
        # If the number of set bits
        # is odd, then add to the
        # number of multiples
        parity[bin(i).count('1') & 1] += (m // mult)
  
    return parity[1] - parity[0]
  
# Function calculates all number
# not greater than 'm' which are
# relatively prime with n.
def countRelPrime(n, m):
  
    a = [0] * 20
    i = 0
    j = 0
    pz = len(prime)
    while (n != 1 and i < pz):
  
        # If square of the prime number
        # is greater than 'n', it can't
        # be a factor of 'n'
        if (prime[i] * prime[i] > n):
            break
  
        # If prime is a factor of
        # n then increment count
        if (n % prime[i] == 0):
            a[j] = prime[i]
            j += 1
  
        while (n % prime[i] == 0):
            n //= prime[i]
        i += 1
  
    if (n != 1):
        a[j] = n
        j += 1
    return m - count(a, j, m)
  
def countRelPrimeInRange(n, l, r):
      
    sieve(floor(sqrt(maxN)))
    result = (countRelPrime(n, r) -
              countRelPrime(n, l - 1))
    print(result)
  
# Driver code
if __name__ == '__main__':
      
    N = 7
    L = 3
    R = 9
      
    countRelPrimeInRange(N, L, R)
  
# This code is contributed by mohit kumar 29

chevron_right


Output:

6

competitive-programming-img




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : mohit kumar 29