给定两个正整数L和R ,任务是找出范围[L, R]之间的值总数,使得从1到N的素数计数也是素数。
例子:
Input: L = 3, R = 10
Output: 4
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: 5
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].
天真的方法:
解决该问题的最简单的方法是遍历用于在范围[1,L – 1]的所有值计算在该范围内的素数的数量。计算一次,检查计数是否为素数。现在,开始一一遍历[L, R]范围内的值并检查数字是否为素数并相应地增加计数。对于每个更新的计数,检查它是否是质数,并相应地更新给定范围内所需数字的计数。
时间复杂度: O(R 2 )
有效的方法:
上述方法可以通过埃拉托色尼筛法进一步优化。请按照以下步骤解决问题:
- 使用筛子找出直到R 的所有素数。
- 维护一个频率数组,以存储直到R 的所有值的素数计数。
- 创建另一个计数数组(比如freqPrime[] ),如果到i的总素数的累积计数本身就是一个素数,则在位置i处加 1。
- 现在对于任何范围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
Javascript
5
时间复杂度: O(R*log(log(R)))
辅助空间: O(R)