Count of numbers up to N having only 4 factors or divisors
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 <bits/stdc++.h> 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<Integer> 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<Integer> 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<Integer> 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<Integer> 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<Integer> 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<Integer> 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)
Please Login to comment...