Count of all values of N in [L, R] such that count of primes upto N is also prime

Given two positive integers L and R, the task is to find out the total number of values between range [L, R] such that the count of prime numbers from 1 to N is also prime.
Examples: 

Input: L = 3, R = 10 
Output:
Explanation: 
Number of primes upto 3, 4, 5, 6, 7, 8, 9 and 10 are 2, 2, 3, 3, 4, 4, 4 and 4 respectively. So, there are a total 4 such numbers {3, 4, 5, 6}[3, 10].
Input: L = 4, R = 12 
Output:
Explanation: 
Number of primes upto 4, 5, 6, 7, 8, 9, 10, 11 and 12 are 2, 3, 3, 4, 4, 4, 4, 5 and 5 respectively. So, there are total 5 such numbers {4, 5, 6, 11, 12} which satisfy the condition in the range [4, 12]. 
 

Naive Approach: 
The simplest approach to solve the problem is to traverse for all values in the range [1, L – 1] count the number of primes in that range. Once, calculated, check if the count is prime or not. Now, start traversing the values in the range [L, R] one by one and check if the number is prime or not and increase the count accordingly. For every updated count check if it is prime or not and accordingly update the count of required numbers from the given range. 
Time Complexity: O(R2)
Efficient Approach: 
The above approach can be further optimized by the Sieve of Eratosthenes. Follow the steps below to solve the problem:  

  1. Find all prime numbers up to R using a sieve.
  2. Maintain a frequency array to store the count of primes up to for all values up to R.
  3. Create another count array(say freqPrime[]) and add 1 at position i if the cumulative count of total primes up to i is itself a prime number.
  4. Now for any range L to R, then the number of crazy primes can be calculated by freqPrime[R] – freqPrime[L – 1].

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>
using namespace std;
 
// Function to count the number of
// crazy primes in the given range [L, R]
int count_crazy_primes(int L, int R)
{
    // Stores all primes
    int prime[R + 1] = { 0 };
 
    // Stores count of primes
    int countPrime[R + 1] = { 0 };
 
    // Stores if frequency of
    // primes is a prime or not
    // upto each index
    int freqPrime[R + 1] = { 0 };
 
    prime[0] = prime[1] = 1;
    // Sieve of Eratosthenes
    for (int p = 2; p * p <= R; p++) {
        if (prime[p] == 0) {
            for (int i = p * p;
                 i <= R; i += p)
 
                prime[i] = 1;
        }
    }
 
    // Count primes
    for (int i = 1; i <= R; i++) {
        countPrime[i] = countPrime[i - 1];
 
        // If i is a prime
        if (!prime[i]) {
            countPrime[i]++;
        }
    }
 
    // Stores frequency of primes
    for (int i = 1; i <= R; i++) {
        freqPrime[i] = freqPrime[i - 1];
 
        // If the frequency of primes
        // is a prime
        if (!prime[countPrime[i]]) {
 
            // Increase count of
            // required numbers
            freqPrime[i]++;
        }
    }
 
    // Return the required count
    return (freqPrime[R]
            - freqPrime[L - 1]);
}
 
// Driver Code
int main()
{
    // Given Range
    int L = 4, R = 12;
 
    // Function Call
    cout << count_crazy_primes(L, R);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
class GFG{
 
// Function to count the number of
// crazy primes in the given range [L, R]
static int count_crazy_primes(int L, int R)
{
     
    // Stores all primes
    int prime[] = new int[R + 1];
 
    // Stores count of primes
    int countPrime[] = new int[R + 1];
 
    // Stores if frequency of
    // primes is a prime or not
    // upto each index
    int freqPrime[] = new int[R + 1];
     
    prime[0] = 1;
    prime[1] = 1;
     
    // Sieve of Eratosthenes
    for(int p = 2; p * p <= R; p++)
    {
       if (prime[p] == 0)
       {
           for(int i = p * p;
                   i <= R; i += p)
              prime[i] = 1;
       }
    }
 
    // Count primes
    for(int i = 1; i <= R; i++)
    {
       countPrime[i] = countPrime[i - 1];
        
       // If i is a prime
       if (prime[i] != 0)
       {
           countPrime[i]++;
       }
    }
 
    // Stores frequency of primes
    for(int i = 1; i <= R; i++)
    {
       freqPrime[i] = freqPrime[i - 1];
        
       // If the frequency of primes
       // is a prime
       if (prime[countPrime[i]] != 0)
       {
            
           // Increase count of
           // required numbers
           freqPrime[i]++;
       }
    }
 
    // Return the required count
    return (freqPrime[R] -
            freqPrime[L - 1]);
}
 
// Driver code
public static void main (String[] args)
{
     
    // Given range
    int L = 4, R = 12;
 
    // Function call
    System.out.println(count_crazy_primes(L, R));
}
}
 
// This code is contributed by Pratima Pandey    

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
class GFG{
   
// Function to count the number of
// crazy primes in the given range [L, R]
static int count_crazy_primes(int L,
                              int R)
{     
    // Stores all primes
    int []prime = new int[R + 1];
   
    // Stores count of primes
    int []countPrime = new int[R + 1];
   
    // Stores if frequency of
    // primes is a prime or not
    // upto each index
    int []freqPrime = new int[R + 1];
       
    prime[0] = 1;
    prime[1] = 1;
       
    // Sieve of Eratosthenes
    for(int p = 2; p * p <= R; p++)
    {
       if (prime[p] == 0)
       {
           for(int i = p * p; i <= R;
               i += p)
              prime[i] = 1;
       }
    }
   
    // Count primes
    for(int i = 1; i <= R; i++)
    {
       countPrime[i] = countPrime[i - 1];
          
       // If i is a prime
       if (prime[i] != 0)
       {
           countPrime[i]++;
       }
    }
   
    // Stores frequency of primes
    for(int i = 1; i <= R; i++)
    {
       freqPrime[i] = freqPrime[i - 1];
          
       // If the frequency of primes
       // is a prime
       if (prime[countPrime[i]] != 0)
       {            
           // Increase count of
           // required numbers
           freqPrime[i]++;
       }
    }
   
    // Return the required count
    return (freqPrime[R] -
            freqPrime[L - 1]);
}
   
// Driver code
public static void Main(String[] args)
{      
    // Given range
    int L = 4, R = 12;
   
    // Function call
    Console.WriteLine(
            count_crazy_primes(L, R));
}
}
// This code is contributed by 29AjayKumar

chevron_right


Output: 

5


 

Time Complexity: O(R*log(log(R))) 
Auxillary Space: O(R)

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.