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

• Last Updated : 14 Jun, 2022

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;` `}`

## 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`

Output

`2`

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

My Personal Notes arrow_drop_up
Recommended Articles
Page :