 Open in App
Not now

# Count of numbers up to N having only 4 factors or divisors

• Last Updated : 07 Feb, 2023

Given an integer N, find the number of natural numbers less than or equal to N and have 4 factors.

Example:

Input: N = 8
Output: 2
Explanation: {1} is divisor set of 1
{1, 2} is divisor set of 2
{1, 3} is divisor set of 3
{1, 2, 4} is divisor set of 4
{1, 5} is divisor set of 5
{1, 2, 3, 6} is divisor set of 6
{1, 7} is divisor set of 7
{1, 2, 4, 8} is divisor set of 8
So, 6 and 8 are only natural numbers less than or equal to N and count of divisors 4.

Input: N = 2
Output: 0

Approach: The idea to solve the problem is based on the following observation:

• Any number M can be written in form M = p1e1 * p2e2 *  . . . where (p1, p2 . . .) are primes and (e1, e2 . . .) are respective exponents.
• The total number of factors of M is therefore (e + 1)*(e + 1)* . . .
• From above points, for the count of divisors of a natural number to be 4, there are two cases:-
• Case-1: N = p1 * p2 (where p1 and p2 are two distinct prime numbers)
• Case-2: N = p3 (where p is a prime number)
• So there must be two primes whose multiplication is less than N or one prime whose cube is less than N.

Follow the steps mentioned below to solve the problem:

• Find all the prime numbers less than or equal to N using the sieve of Eratosthenes.
• For Case-1 iterate through all prime numbers and use binary search to find a number of primes whose product is at most N.
• For Case-2, do a binary search to find the number of primes whose cube is less than or equal to N.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ``using` `namespace` `std;` `// Function to find primes <= N``vector<``int``> SieveOfEratosthenes(``int` `n)``{``    ``// Create a boolean array``    ``// "prime[0..n]" and initialize``    ``// all entries it as true.``    ``// A value in prime[i] will``    ``// finally be false if i is``    ``// Not a prime, else true.``    ``bool` `prime[n + 1];``    ``memset``(prime, ``true``, ``sizeof``(prime));` `    ``for` `(``long` `long` `int` `p = 2;``         ``p * p <= n; p++) {` `        ``// If prime[p] is not changed,``        ``// then it is a prime``        ``if` `(prime[p] == ``true``) {``            ``// Update all multiples``            ``// of p greater than or``            ``// equal to the square of it``            ``for` `(``long` `long` `int` `i = p * p;``                 ``i <= n; i += p)``                ``prime[i] = ``false``;``        ``}``    ``}` `    ``// Vector for storing prime number``    ``// less than or equal to N``    ``vector<``int``> primes;` `    ``// Store all prime numbers``    ``for` `(``int` `p = 2; p <= n; p++)``        ``if` `(prime[p])``            ``primes.push_back(p);` `    ``return` `primes;``}` `// Find floor of cube root of N``int` `primeCubic(vector<``int``>& primes, ``int` `N)``{` `    ``// Val stores cube root of N``    ``long` `long` `int` `l = 0, r = N, mid, val;` `    ``// Binary search loop for finding``    ``// floor of cube root of N``    ``while` `(l <= r) {``        ``mid = (l + r) / 2;``        ``if` `((mid * mid * mid) <= N) {``            ``val = mid;``            ``l = mid + 1;``        ``}``        ``else` `{``            ``r = mid - 1;``        ``}``    ``}` `    ``// Iterator for finding index with``    ``// value just greater than Val in primes``    ``auto` `it = upper_bound(primes.begin(),``                          ``primes.end(), val);``    ``it--;` `    ``return` `(it - primes.begin() + 1);``}` `// Function to find primes with product <= N``int` `primeProduct(vector<``int``>& primes,``                 ``int` `N)``{``    ``// Stores the answer``    ``int` `answer = 0;` `    ``// Iterator storing pointer to``    ``// current prime``    ``auto` `cur = primes.begin();` `    ``// Loop for traversing all primes``    ``// Find number of indices less than``    ``// current indices for which product``    ``// is less than or equal to N``    ``for` `(``auto` `i : primes) {``        ``long` `long` `int` `add``            ``= upper_bound(primes.begin(),``                          ``cur, (N / i))``              ``- primes.begin();``        ``answer += add;``        ``cur++;``    ``}``    ``return` `answer;``}` `// Function to find the total count``int` `print(``int` `N)``{``    ``vector<``int``> primes``        ``= SieveOfEratosthenes(N);` `    ``int` `answer = 0;``    ``answer += primeCubic(primes, N);``    ``answer += primeProduct(primes, N);``    ``return` `answer;``}` `// Driver code``int` `main()``{``    ``int` `N = 8;` `    ``// Print function Call``    ``cout << print(N);``    ``return` `0;``}`

## Java

 `// Java program for above approach``import` `java.util.*;` `public` `class` `Solution``{` `  ``// Function to find primes <= N``  ``static` `ArrayList SieveOfEratosthenes(``int` `n)``  ``{` `    ``// Create a boolean array``    ``// "prime[0..n]" and initialize``    ``// all entries it as true.``    ``// A value in prime[i] will``    ``// finally be false if i is``    ``// Not a prime, else true.``    ``boolean``[] prime = ``new` `boolean``[n + ``1``];``    ``Arrays.fill(prime, ``true``);` `    ``for` `(``int` `p = ``2``; p * p <= n; p++) {` `      ``// If prime[p] is not changed,``      ``// then it is a prime``      ``if` `(prime[p] == ``true``) {``        ``// Update all multiples``        ``// of p greater than or``        ``// equal to the square of it``        ``for` `(``int` `i = p * p; i <= n; i += p)``          ``prime[i] = ``false``;``      ``}``    ``}` `    ``// Vector for storing prime number``    ``// less than or equal to N``    ``ArrayList primes = ``new` `ArrayList<>();` `    ``// Store all prime numbers``    ``for` `(``int` `p = ``2``; p <= n; p++)``      ``if` `(prime[p])``        ``primes.add(p);` `    ``return` `primes;``  ``}` `  ``static` `int` `upper_bound(ArrayList arr, ``int` `lo,``                         ``int` `hi, ``int` `key)``  ``{``    ``int` `mid, N = arr.size();` `    ``// Initialise starting index and``    ``// ending index``    ``int` `low = lo;``    ``int` `high = hi;` `    ``// Till low is less than high``    ``while` `(low < high && low != N) {``      ``mid = low + (high - low) / ``2``;` `      ``// If key is greater than or equal``      ``// to arr[mid], then find in``      ``// right subarray``      ``if` `(key >= arr.get(mid)) {``        ``low = mid + ``1``;``      ``}` `      ``// If key is less than arr[mid]``      ``// then find in left subarray``      ``else` `{``        ``high = mid;``      ``}``    ``}``    ``return` `low;``  ``}``  ``// Find floor of cube root of N``  ``static` `int` `primeCubic(ArrayList primes, ``int` `N)``  ``{` `    ``// Val stores cube root of N``    ``int` `l = ``0``, r = N, mid, val = ``0``;` `    ``// Binary search loop for finding``    ``// floor of cube root of N``    ``while` `(l <= r) {``      ``mid = (l + r) / ``2``;``      ``if` `((mid * mid * mid) <= N) {``        ``val = mid;``        ``l = mid + ``1``;``      ``}``      ``else` `{``        ``r = mid - ``1``;``      ``}``    ``}` `    ``// Iterator for finding index with``    ``// value just greater than Val in primes``    ``int` `it = upper_bound(primes, ``0``, primes.size(), val);``    ``it--;` `    ``return` `(it + ``1``);``  ``}` `  ``// Function to find primes with product <= N``  ``static` `int` `primeProduct(ArrayList primes,``                          ``int` `N)``  ``{``    ``// Stores the answer``    ``int` `answer = ``0``;` `    ``// Iterator storing pointer to``    ``// current prime``    ``int` `cur = ``0``;` `    ``// Loop for traversing all primes``    ``// Find number of indices less than``    ``// current indices for which product``    ``// is less than or equal to N``    ``for` `(``int` `i : primes) {``      ``int` `add = upper_bound(primes, ``0``, cur, (N / i));``      ``answer += add;``      ``cur++;``    ``}``    ``return` `answer;``  ``}` `  ``// Function to find the total count``  ``static` `int` `print(``int` `N)``  ``{``    ``ArrayList primes = SieveOfEratosthenes(N);` `    ``int` `answer = ``0``;``    ``answer += primeCubic(primes, N);``    ``answer += primeProduct(primes, N);``    ``return` `answer;``  ``}` `  ``// Driver code``  ``public` `static` `void` `main(String[] args)``  ``{``    ``int` `N = ``8``;``    ` `    ``// Print function Call``    ``System.out.println(print(N));``  ``}``}` `// This code is contributed by karandeep1234.`

## Python3

 `# Python3 program for the above approach``import` `bisect` `# Function to find primes <= N``def` `SieveOfEratosthenes(n):` `    ``# Create a boolean array``    ``# "prime[0..n]" and initialize``    ``# all entries it as true.``    ``# A value in prime[i] will``    ``# finally be false if i is``    ``# Not a prime, else true.``    ``prime ``=` `[``True``] ``*` `(n ``+` `1``)``    ` `    ``for` `p ``in` `range``(``2``, ``1` `+` `int``(n ``*``*` `0.5``)):``        ` `        ``# If prime[p] is not changed,``        ``# then it is a prime``        ``if` `(prime[p] ``=``=` `True``):``            ``# Update all multiples``            ``# of p greater than or``            ``# equal to the square of it``            ``for` `i ``in` `range``(p ``*` `p, n ``+` `1``, p):``                ``prime[i] ``=` `False` `    ``# Vector for storing prime number``    ``# less than or equal to N``    ``primes ``=` `[]` `    ``# Store all prime numbers``    ``for` `p ``in` `range``(``2``, n ``+` `1``):``        ``if` `prime[p]:``            ``primes.append(p)`  `    ``return` `primes`  `# Find floor of cube root of N``def` `primeCubic(primes, N):` `    ``#Val stores cube root of N``    ``l ``=` `0``    ``r ``=` `N` `    ``# Binary search loop for finding``    ``# floor of cube root of N``    ``while` `(l <``=` `r):``        ``mid ``=` `(l ``+` `r) ``/``/` `2``        ``if` `((mid ``*` `mid ``*` `mid) <``=` `N):``            ``val ``=` `mid``            ``l ``=` `mid ``+` `1``        ` `        ``else``:``            ``r ``=` `mid ``-` `1` `    ``# Iterator for finding index with``    ``# value just greater than Val in primes``    ``it ``=` `bisect.bisect_right(primes, val)` `    ``return` `it` `# Function to find primes with product <= N``def` `primeProduct(primes, N):` `    ``# Stores the answer``    ``answer ``=` `0` `    ``# Iterator storing pointer to``    ``# current prime``    ``cur ``=` `0` `    ``# Loop for traversing all primes``    ``# Find number of indices less than``    ``# current indices for which product``    ``# is less than or equal to N``    ``for` `i ``in` `primes:``        ``add ``=` `bisect.bisect_right(primes[:cur], N ``/``/` `i)``        ``answer ``+``=` `add``        ``cur ``+``=` `1` `    ``return` `answer` `# Function to find the total count``def` `print_(N):` `    ``primes ``=` `SieveOfEratosthenes(N)` `    ``answer ``=` `0``    ``answer ``+``=` `primeCubic(primes, N)``    ``answer ``+``=` `primeProduct(primes, N)``    ``return` `answer`  `# Driver code``N ``=` `8` `# Print function Call``print``(print_(N))` `# This code is contributed by phasing17`

## C#

 `using` `System;``using` `System.Collections.Generic;``class` `GFG``{``  ` `  ``// Function to find primes <= N``  ``static` `int``[] SieveOfEratosthenes(``int` `n)``  ``{``    ` `    ``// Create a boolean array``    ``// "prime[0..n]" and initialize``    ``// all entries it as true.``    ``// A value in prime[i] will``    ``// finally be false if i is``    ``// Not a prime, else true.``    ``bool``[] prime = ``new` `bool``[n + 1];``    ``for` `(``int` `i = 0; i <= n; i++) {``      ``prime[i] = ``true``;``    ``}` `    ``for` `(``int` `p = 2; p * p <= n; p++) {` `      ``// If prime[p] is not changed,``      ``// then it is a prime``      ``if` `(prime[p] == ``true``) {``        ``// Update all multiples``        ``// of p greater than or``        ``// equal to the square of it``        ``for` `(``int` `i = p * p; i <= n; i += p)``          ``prime[i] = ``false``;``      ``}``    ``}` `    ``// Array for storing prime number``    ``// less than or equal to N``    ``// int []primes= new int[];``    ``List<``int``> primes = ``new` `List<``int``>();``    ` `    ``// Store all prime numbers``    ``for` `(``int` `p = 2; p <= n; p++)``      ``if` `(prime[p])``        ``primes.Add(p);` `    ``return` `primes.ToArray();``  ``}` `  ``static` `int` `upper_bound(``int``[] arr, ``int` `N, ``int` `X)``  ``{``    ``int` `mid;``    ``int` `low = 0;``    ``int` `high = N;``    ``while` `(low < high) {``      ``mid = low + (high - low) / 2;``      ``if` `(X >= arr[mid])``        ``low = mid + 1;``      ``else``        ``high = mid;``    ``}``    ``if` `(low < N && arr[low] <= X)``      ``low++;``    ``return` `low;``  ``}``  ` `  ``// Find floor of cube root of N``  ``static` `int` `primeCubic(``int``[] primes, ``int` `N)``  ``{` `    ``// Val stores cube root of N``    ``int` `l = 0, r = N, mid, val = 0;` `    ``// Binary search loop for finding``    ``// floor of cube root of N``    ``while` `(l <= r) {``      ``mid = (l + r) / 2;``      ``if` `((mid * mid * mid) <= N) {``        ``val = mid;``        ``l = mid + 1;``      ``}``      ``else` `{``        ``r = mid - 1;``      ``}``    ``}` `    ``// Iterator for finding index with``    ``// value just greater than Val in primes``    ``int` `it = upper_bound(primes, primes.Length, val);``    ``return` `it;``  ``}``  ` `  ``// Function to find primes with product <= N``  ``static` `int` `primeProduct(``int``[] primes, ``int` `N)``  ``{``    ` `    ``// Stores the answer``    ``int` `answer = 0;``    ` `    ``// Iterator storing pointer to``    ``// current prime``    ``int` `cur = 0;` `    ``// Loop for traversing all primes``    ``// Find number of indices less than``    ``// current indices for which product``    ``// is less than or equal to N``    ``for` `(``int` `i = 0; i < primes.Length; i++) {``      ``int` `add``        ``= upper_bound(primes, cur, (N / primes[i]));``      ``answer += add;``      ``cur++;``    ``}``    ``return` `answer;``  ``}` `  ``// Function to find the total count``  ``static` `int` `print(``int` `N)``  ``{``    ``int``[] primes = SieveOfEratosthenes(N);` `    ``int` `answer = 0;``    ``answer += primeCubic(primes, N);``    ``answer += primeProduct(primes, N);``    ``return` `answer;``  ``}``  ``static` `void` `Main()``  ``{``    ``int` `N = 8;` `    ``// Print function Call``    ``Console.Write(print(N));``  ``}``}` `// This code is contributed by garg28harsh.`

## Javascript

 `// Function to find primes <=N``const SieveOfEratosthenes = (n) => {` `    ``// Create a boolean array``    ``// "prime[0..n]" and initialize``    ``// all entries it as true.``    ``// A value in prime[i] will``    ``// finally be false if i is``    ``// Not a prime, else true.``  ``let prime = Array(n + 1).fill(``true``);``  ``for` `(let p = 2; p * p <= n; p++)``  ``{``  ` `      ``// If prime[p] is not changed,``      ``// then it is a prime``    ``if` `(prime[p])``    ``{``    ` `      ``// Update all multiples``      ``// of p greater than or``      ``// equal to the square of it``      ``for` `(let i = p * p; i <= n; i += p)``        ``prime[i] = ``false``;``    ``}``  ``}``  ` `// Vector for storing prime number``// less than or equal to N``  ``let primes = [];``  ` `// Store all prime numbers``  ``for` `(let p = 2; p <= n; p++)``    ``if` `(prime[p])``      ``primes.push(p);` `  ``return` `primes;``}` `const upper_bound = (arr, lo, hi, key) => {``  ``let mid, N = arr.length;``  ` `// Initialise starting index and``// ending index``  ``let low = lo;``  ``let high = hi;``  ` `// Till low is less than high``  ``while` `(low < high && low != N) {``    ``mid = low + Math.floor((high - low) / 2);``    ` `    ``// If key is greater than or equal``      ``// to arr[mid], then find in``      ``// right subarray``    ``if` `(key >= arr[mid]) {``      ``low = mid + 1;``    ``}``    ` `    ``// If key is less than arr[mid]``    ``// then find in left subarray``    ``else` `{``      ``high = mid;``    ``}``  ``}``  ``return` `low;``}` `// Find floor of cube root of N``const primeCubic = (primes, N) => {` `  ``// Val stores cube root of N``  ``let l = 0, r = N, mid, val = 0;``  ` ` ``// Binary search loop for finding``    ``// floor of cube root of N``  ``while` `(l <= r) {``    ``mid = Math.floor((l + r) / 2);``    ``if` `((mid * mid * mid) <= N) {``      ``val = mid;``      ``l = mid + 1;``    ``}``    ``else` `{``      ``r = mid - 1;``    ``}``  ``}``  ` `    ``// Iterator for finding index with``    ``// value just greater than Val in primes``  ``let it = upper_bound(primes, 0, primes.length, val);``  ``it--;` `  ``return` `(it + 1);``}` ` ``// Function to find primes with product <= N``const primeProduct = (primes, N) => {``  ``let answer = 0;``  ` `    ``// Iterator storing pointer to``    ``// current prime``  ``let cur = 0;``  ` `   ``// Loop for traversing all primes``    ``// Find number of indices less than``    ``// current indices for which product``    ``// is less than or equal to N``  ``for` `(let i of primes) {``    ``let add = upper_bound(primes, 0, cur, Math.floor(N / i));``    ``answer += add;``    ``cur++;``  ``}``  ``return` `answer;``}` `// Function to find the total count``const print = (N) => {``  ``let primes = SieveOfEratosthenes(N);` `  ``let answer = 0;``  ``answer += primeCubic(primes, N);``  ``answer += primeProduct(primes, N);``  ``return` `answer;``}` `console.log(print(8));` `// This code is contributed by anskalyan3.`

Output

`2`

Time Complexity: O(N * log(logN) + N + logN) ≈ O(N * log (logN))
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up