First element of every K sets having consecutive elements with exactly K prime factors less than N

Given two integers N and K, the task is to find the first element for every set of K consecutive elements which have exactly K prime factors and are less than N.

Examples:

Input: N = 30, K = 2
Output: 14 20 21
Explanation:
Numbers which have prime factors equals to 2 less than 30 = { 14, 15, 18, 20, 21, 22, 24, 26, 28 }.
In the above examples, for K = 2 (14, 15) (20, 21) (21, 22) only forms such sets and therefore the series is 14, 20, 21.

Input: N = 1000, K = 3
Output: 644 740 804 986

Naive Approach: The naive approach is to iterate from 2 to N and check that every K consecutive number forms a set having K prime factors for each element in the set. If “Yes” then print the first element of this set and check for next K elements.



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

Efficient Approach: The above approach can be optimized by precomputing the number of prime factors till N and check for every K consecutive elements count having K prime factors. Below are the steps:

  1. Create a smallest prime factor array spf[] which stores the smallest prime factors for every number till N using Sieve of Eratosthenes.
  2. Using the above step, count the number of prime factors till each number N
  3. Store the number in the array(say result[]) whose count of prime factor is K.
  4. For each element of the array result[] check if there exists K consecutive numbers then print the first element of K consecutive numbers.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
  
#include <bits/stdc++.h>
#define x 2000021
using namespace std;
  
// For storing smallest prime factor
long long int v[x];
  
// Function construct smallest
// prime factor array
void sieve()
{
    v[1] = 1;
  
    // Mark smallest prime factor for
    // every number to be itself.
    for (long long int i = 2; i < x; i++)
        v[i] = i;
  
    // separately mark spf for every even
    // number as 2
    for (long long int i = 4; i < x; i += 2)
        v[i] = 2;
  
    for (long long int i = 3; i * i < x; i++) {
  
        // Check if i is prime
        if (v[i] == i) {
  
            // Mark SPF for all numbers
            // divisible by i
            for (long long int j = i * i;
                 j < x; j += i) {
  
                // Mark spf[j] if it is
                // not previously marked
                if (v[j] == j) {
                    v[j] = i;
                }
            }
        }
    }
}
  
// Function for counts total number
// of prime factors
long long int prime_factors(long long n)
{
    set<long long int> s;
  
    while (n != 1) {
        s.insert(v[n]);
        n = n / v[n];
    }
    return s.size();
}
  
// Function to print elements of sets
// of K consecutive elements having
// K prime factors
void distinctPrimes(long long int m,
                    long long int k)
{
  
    // To store the result
    vector<long long int> result;
    for (long long int i = 14;
         i < m + k; i++) {
  
        // Count number of prime
        // factors of number
        long long count
            = prime_factors(i);
  
        // If number has exactly K
        // factors push in result[]
        if (count == k) {
            result.push_back(i);
        }
    }
  
    long long int p = result.size();
  
    for (long long int index = 0;
         index < p - 1; index++) {
  
        long long element = result[index];
        long long count = 1, z = index;
  
        // Iterate till we get K consecutive
        // elements in result[]
        while (z < p - 1 && count <= k
               && result[z] + 1
                      == result[z + 1]) {
  
            // Count sequence until K
            count++;
            z++;
        }
  
        // Print the element if count >= K
        if (count >= k)
            cout << element << ' ';
    }
}
  
// Driver Code
int main()
{
    // To construct spf[]
    sieve();
  
    // Given N and K
    long long int N = 1000, K = 3;
  
    // Function Call
    distinctPrimes(N, K);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach
import java.util.*;
  
class GFG{
      
static final int x = 2000021
      
// For storing smallest prime factor
static int []v = new int[x];
  
// Function consmallest
// prime factor array
static void sieve()
{
    v[1] = 1;
  
    // Mark smallest prime factor for
    // every number to be itself.
    for(int i = 2; i < x; i++)
        v[i] = i;
  
    // Separately mark spf for every even
    // number as 2
    for(int i = 4; i < x; i += 2)
        v[i] = 2;
  
    for(int i = 3; i * i < x; i++)
    {
          
        // Check if i is prime
        if (v[i] == i) 
        {
  
            // Mark SPF for all numbers
            // divisible by i
            for(int j = i * i; j < x; j += i) 
            {
                  
                // Mark spf[j] if it is
                // not previously marked
                if (v[j] == j) 
                {
                    v[j] = i;
                }
            }
        }
    }
}
  
// Function for counts total number
// of prime factors
static int prime_factors(int n)
{
    HashSet<Integer> s = new HashSet<Integer>();
  
    while (n != 1)
    {
        s.add(v[n]);
        n = n / v[n];
    }
      
    return s.size();
}
  
// Function to print elements of sets
// of K consecutive elements having
// K prime factors
static void distinctPrimes(int m, int k)
{
      
    // To store the result
    Vector<Integer> result = new Vector<Integer>();
    for (int i = 14; i < m + k; i++)
    {
          
        // Count number of prime
        // factors of number
        long count = prime_factors(i);
  
        // If number has exactly K
        // factors push in result[]
        if (count == k)
        {
            result.add(i);
        }
    }
  
    int p = result.size();
    for(int index = 0
            index < p - 1; index++)
    {
          
        long element = result.get(index);
        int count = 1, z = index;
  
        // Iterate till we get K consecutive
        // elements in result[]
        while (z < p - 1 && count <= k && 
                     result.get(z) + 1 == 
                     result.get(z + 1)) 
        {
              
            // Count sequence until K
            count++;
            z++;
        }
          
        // Print the element if count >= K
        if (count >= k)
            System.out.print(element + " ");
    }
}
  
// Driver code
public static void main(String[] args)
{
      
    // To construct spf[]
    sieve();
  
    // Given N and K
    int N = 1000, K = 3;
  
    // Function call
    distinctPrimes(N, K);
}
}
  
// This code is contributed by Princi Singh

chevron_right


Output:

644 740 804 986

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

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 : princi singh