📜  [L,R]中N的所有值的计数,使得直到N的质数也为质数

📅  最后修改于: 2021-05-13 23:10:56             🧑  作者: Mango

给定两个正整数LR ,任务是找出范围[L,R]之间的值的总数,以使从1N的质数的计数也为质数。
例子:

天真的方法:
解决该问题的最简单的方法是遍历用于在范围[1,L – 1]的所有值计算在该范围内的素数的数量。计算一次后,检查计数是否为素数。现在,开始一个遍历[L,R]范围内的值,并检查数字是否为质数,并相应地增加计数。对于每个更新的计数,请检查其是否为质数,并相应地从给定范围内更新所需数字的计数。
时间复杂度: O(R 2 )
高效方法:
可以通过Eratosthenes筛子进一步优化上述方法。请按照以下步骤解决问题:

  1. 使用筛子查找所有不超过R的质数。
  2. 维护一个频率数组,以存储最多到R的所有值的质数计数。
  3. 创建另一个计数数组(例如freqPrime [] ),如果直到i的全部素数的累计计数本身就是素数,则在位置i处加1。
  4. 现在,对于从L到R的任何范围,可以通过freqPrime [R] – freqPrime [L – 1]计算疯狂素数。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
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;
}


Java
// 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


Python3
# Python3 program for the above approach
 
# Function to count the number of
# crazy primes in the given range [L, R]
def count_crazy_primes(L, R):
 
    # Stores all primes
    prime = [0] * (R + 1)
 
    # Stores count of primes
    countPrime = [0] * (R + 1)
 
    # Stores if frequency of
    # primes is a prime or not
    # upto each index
    freqPrime = [0] * (R + 1)
 
    prime[0] = prime[1] = 1
     
    # Sieve of Eratosthenes
    p = 2
    while p * p <= R:
        if (prime[p] == 0):
            for i in range (p * p,
                            R + 1 , p):
                prime[i] = 1
        p += 1
    
    # Count primes
    for i in range (1 , R + 1):
        countPrime[i] = countPrime[i - 1]
 
        # If i is a prime
        if (not prime[i]):
            countPrime[i] += 1
 
    # Stores frequency of primes
    for i in range (1, R + 1):
        freqPrime[i] = freqPrime[i - 1]
 
        # If the frequency of primes
        # is a prime
        if (not prime[countPrime[i]]):
 
            # Increase count of
            # required numbers
            freqPrime[i] += 1
 
    # Return the required count
    return (freqPrime[R] -
            freqPrime[L - 1])
 
# Driver Code
if __name__ =="__main__":
   
    # Given Range
    L = 4
    R = 12
 
    # Function Call
    print(count_crazy_primes(L, R))
 
# This code is contributed by Chitranayal


C#
// 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


输出:
5




时间复杂度: O(R * log(log(R)))
辅助空间: O(R)