给定两个整数L和R,则任务是从其总和是在范围[L,R]为素数的范围内[L,R]计数对的数目。
例子:
Input: L = 1, R = 5
Output: 4
Explanation: Pairs whose sum is a prime number and in the range [L, R] are { (1, 1), (1, 2), (1, 4), (2, 3) }. Therefore, the required output is 4.
Input: L = 1, R = 100
Output: 518
天真的方法:解决此问题的最简单方法是从[1,R ]范围内生成所有可能的对,并针对每对,检查该对元素的和是否为[L,R]范围内的质数。或不。如果发现为真,则增加count 。最后,打印count的值。
时间复杂度:O(N 5/2)
辅助空间: O(1)
高效方法:为了优化上述方法,该思想基于以下观察结果:
If N is a prime number, then pairs whose sum is N are { (1, N – 1), (2, N – 2), ….., floor(N / 2), ceil(N / 2) }. Therefore, total count of pairs whose sum is N = N / 2
请按照以下步骤解决问题:
- 初始化一个变量,例如cntPairs,以存储对的计数,以使该对的元素之和为质数,且在[L,R]范围内。
- 使用Eratosthenes的Sieve初始化一个数组,例如segmentedSieve [],以存储[L,R]范围内的所有素数。
- 遍历线段
tedSieve []使用变量i并检查i是否为质数。如果发现为真,则将cntPairs的值增加(i / 2)。 - 最后,打印cntPairs的值。
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Function to find all prime numbers in range
// [1, lmt] using sieve of Eratosthenes
void simpleSieve(int lmt, vector& prime)
{
// segmentedSieve[i]: Stores if i is
// a prime number (True) or not (False)
bool Sieve[lmt + 1];
// Initialize all elements of
// segmentedSieve[] to false
memset(Sieve, true, sizeof(Sieve));
// Set 0 and 1 as non-prime
Sieve[0] = Sieve[1] = false;
// Iterate over the range [2, lmt]
for (int i = 2; i <= lmt; ++i) {
// If i is a prime number
if (Sieve[i] == true) {
// Append i into prime
prime.push_back(i);
// Set all multiple of i non-prime
for (int j = i * i; j <= lmt; j += i) {
// Update Sieve[j]
Sieve[j] = false;
}
}
}
}
// Function to find all the prime numbers
// in the range [low, high]
vector SegmentedSieveFn(
int low, int high)
{
// Stores square root of high + 1
int lmt = floor(sqrt(high)) + 1;
// Stores all the prime numbers
// in the range [1, lmt]
vector prime;
// Find all the prime numbers in
// the range [1, lmt]
simpleSieve(lmt, prime);
// Stores count of elements in
// the range [low, high]
int n = high - low + 1;
// segmentedSieve[i]: Check if (i - low)
// is a prime number or not
vector segmentedSieve(n + 1, true);
// Traverse the array prime[]
for (int i = 0; i < prime.size(); i++) {
// Store smallest multiple of prime[i]
// in the range[low, high]
int lowLim = floor(low / prime[i])
* prime[i];
// If lowLim is less than low
if (lowLim < low) {
// Update lowLim
lowLim += prime[i];
}
// Iterate over all multiples of prime[i]
for (int j = lowLim; j <= high;
j += prime[i]) {
// If j not equal to prime[i]
if (j != prime[i]) {
// Update segmentedSieve[j - low]
segmentedSieve[j - low] = false;
}
}
}
return segmentedSieve;
}
// Function to count the number of pairs
// in the range [L, R] whose sum is a
// prime number in the range [L, R]
int countPairsWhoseSumPrimeL_R(int L, int R)
{
// segmentedSieve[i]: Check if (i - L)
// is a prime number or not
vector segmentedSieve
= SegmentedSieveFn(L, R);
// Stores count of pairs whose sum of
// elements is a prime and in range [L, R]
int cntPairs = 0;
// Iterate over [L, R]
for (int i = L; i <= R; i++) {
// If (i - L) is a prime
if (segmentedSieve[i - L]) {
// Update cntPairs
cntPairs += i / 2;
}
}
return cntPairs;
}
// Driver Code
int main()
{
int L = 1, R = 5;
cout << countPairsWhoseSumPrimeL_R(L, R);
return 0;
}
Java
// Java program to implement
// the above approach
import java.io.*;
import java.util.*;
class GFG{
// Function to find all prime numbers in range
// [1, lmt] using sieve of Eratosthenes
static ArrayList simpleSieve(int lmt,
ArrayList prime)
{
// segmentedSieve[i]: Stores if i is
// a prime number (True) or not (False)
boolean[] Sieve = new boolean[lmt + 1];
// Initialize all elements of
// segmentedSieve[] to false
Arrays.fill(Sieve, true);
// Set 0 and 1 as non-prime
Sieve[0] = Sieve[1] = false;
// Iterate over the range [2, lmt]
for(int i = 2; i <= lmt; ++i)
{
// If i is a prime number
if (Sieve[i] == true)
{
// Append i into prime
prime.add(i);
// Set all multiple of i non-prime
for(int j = i * i; j <= lmt; j += i)
{
// Update Sieve[j]
Sieve[j] = false;
}
}
}
return prime;
}
// Function to find all the prime numbers
// in the range [low, high]
static boolean[] SegmentedSieveFn(int low, int high)
{
// Stores square root of high + 1
int lmt = (int)(Math.sqrt(high)) + 1;
// Stores all the prime numbers
// in the range [1, lmt]
ArrayList prime = new ArrayList();
// Find all the prime numbers in
// the range [1, lmt]
prime = simpleSieve(lmt, prime);
// Stores count of elements in
// the range [low, high]
int n = high - low + 1;
// segmentedSieve[i]: Check if (i - low)
// is a prime number or not
boolean[] segmentedSieve = new boolean[n + 1];
Arrays.fill(segmentedSieve, true);
// Traverse the array prime[]
for(int i = 0; i < prime.size(); i++)
{
// Store smallest multiple of prime[i]
// in the range[low, high]
int lowLim = (int)(low / prime.get(i)) *
prime.get(i);
// If lowLim is less than low
if (lowLim < low)
{
// Update lowLim
lowLim += prime.get(i);
}
// Iterate over all multiples of prime[i]
for(int j = lowLim; j <= high;
j += prime.get(i))
{
// If j not equal to prime[i]
if (j != prime.get(i))
{
// Update segmentedSieve[j - low]
segmentedSieve[j - low] = false;
}
}
}
return segmentedSieve;
}
// Function to count the number of pairs
// in the range [L, R] whose sum is a
// prime number in the range [L, R]
static int countPairsWhoseSumPrimeL_R(int L, int R)
{
// segmentedSieve[i]: Check if (i - L)
// is a prime number or not
boolean[] segmentedSieve = SegmentedSieveFn(L, R);
// Stores count of pairs whose sum of
// elements is a prime and in range [L, R]
int cntPairs = 0;
// Iterate over [L, R]
for(int i = L; i <= R; i++)
{
// If (i - L) is a prime
if (segmentedSieve[i - L])
{
// Update cntPairs
cntPairs += i / 2;
}
}
return cntPairs;
}
// Driver Code
public static void main(String[] args)
{
int L = 1, R = 5;
System.out.println(
countPairsWhoseSumPrimeL_R(L, R));
}
}
// This code is contributed by akhilsaini
Python
# Python program to implement
# the above approach
import math
# Function to find all prime numbers in range
# [1, lmt] using sieve of Eratosthenes
def simpleSieve(lmt, prime):
# segmentedSieve[i]: Stores if i is
# a prime number (True) or not (False)
Sieve = [True] * (lmt + 1)
# Set 0 and 1 as non-prime
Sieve[0] = Sieve[1] = False
# Iterate over the range [2, lmt]
for i in range(2, lmt + 1):
# If i is a prime number
if (Sieve[i] == True):
# Append i into prime
prime.append(i)
# Set all multiple of i non-prime
for j in range(i * i,
int(math.sqrt(lmt)) + 1, i):
# Update Sieve[j]
Sieve[j] = false
return prime
# Function to find all the prime numbers
# in the range [low, high]
def SegmentedSieveFn(low, high):
# Stores square root of high + 1
lmt = int(math.sqrt(high)) + 1
# Stores all the prime numbers
# in the range [1, lmt]
prime = []
# Find all the prime numbers in
# the range [1, lmt]
prime = simpleSieve(lmt, prime)
# Stores count of elements in
# the range [low, high]
n = high - low + 1
# segmentedSieve[i]: Check if (i - low)
# is a prime number or not
segmentedSieve = [True] * (n + 1)
# Traverse the array prime[]
for i in range(0, len(prime)):
# Store smallest multiple of prime[i]
# in the range[low, high]
lowLim = int(low // prime[i]) * prime[i]
# If lowLim is less than low
if (lowLim < low):
# Update lowLim
lowLim += prime[i]
# Iterate over all multiples of prime[i]
for j in range(lowLim, high + 1, prime[i]):
# If j not equal to prime[i]
if (j != prime[i]):
# Update segmentedSieve[j - low]
segmentedSieve[j - low] = False
return segmentedSieve
# Function to count the number of pairs
# in the range [L, R] whose sum is a
# prime number in the range [L, R]
def countPairsWhoseSumPrimeL_R(L, R):
# segmentedSieve[i]: Check if (i - L)
# is a prime number or not
segmentedSieve = SegmentedSieveFn(L, R)
# Stores count of pairs whose sum of
# elements is a prime and in range [L, R]
cntPairs = 0
# Iterate over [L, R]
for i in range(L, R + 1):
# If (i - L) is a prime
if (segmentedSieve[i - L] == True):
# Update cntPairs
cntPairs += i / 2
return cntPairs
# Driver Code
if __name__ == '__main__':
L = 1
R = 5
print(countPairsWhoseSumPrimeL_R(L, R))
# This code is contributed by akhilsaini
C#
// C# program to implement
// the above approach
using System;
using System.Collections;
class GFG{
// Function to find all prime numbers in range
// [1, lmt] using sieve of Eratosthenes
static ArrayList simpleSieve(int lmt, ArrayList prime)
{
// segmentedSieve[i]: Stores if i is
// a prime number (True) or not (False)
bool[] Sieve = new bool[lmt + 1];
// Initialize all elements of
// segmentedSieve[] to false
Array.Fill(Sieve, true);
// Set 0 and 1 as non-prime
Sieve[0] = Sieve[1] = false;
// Iterate over the range [2, lmt]
for(int i = 2; i <= lmt; ++i)
{
// If i is a prime number
if (Sieve[i] == true)
{
// Append i into prime
prime.Add(i);
// Set all multiple of i non-prime
for(int j = i * i; j <= lmt; j += i)
{
// Update Sieve[j]
Sieve[j] = false;
}
}
}
return prime;
}
// Function to find all the prime numbers
// in the range [low, high]
static bool[] SegmentedSieveFn(int low, int high)
{
// Stores square root of high + 1
int lmt = (int)(Math.Sqrt(high)) + 1;
// Stores all the prime numbers
// in the range [1, lmt]
ArrayList prime = new ArrayList();
// Find all the prime numbers in
// the range [1, lmt]
prime = simpleSieve(lmt, prime);
// Stores count of elements in
// the range [low, high]
int n = high - low + 1;
// segmentedSieve[i]: Check if (i - low)
// is a prime number or not
bool[] segmentedSieve = new bool[n + 1];
Array.Fill(segmentedSieve, true);
// Traverse the array prime[]
for(int i = 0; i < prime.Count; i++)
{
// Store smallest multiple of prime[i]
// in the range[low, high]
int lowLim = (int)(low / (int)prime[i]) *
(int)prime[i];
// If lowLim is less than low
if (lowLim < low)
{
// Update lowLim
lowLim += (int)prime[i];
}
// Iterate over all multiples of prime[i]
for(int j = lowLim; j <= high;
j += (int)prime[i])
{
// If j not equal to prime[i]
if (j != (int)prime[i])
{
// Update segmentedSieve[j - low]
segmentedSieve[j - low] = false;
}
}
}
return segmentedSieve;
}
// Function to count the number of pairs
// in the range [L, R] whose sum is a
// prime number in the range [L, R]
static int countPairsWhoseSumPrimeL_R(int L, int R)
{
// segmentedSieve[i]: Check if (i - L)
// is a prime number or not
bool[] segmentedSieve = SegmentedSieveFn(L, R);
// Stores count of pairs whose sum of
// elements is a prime and in range [L, R]
int cntPairs = 0;
// Iterate over [L, R]
for(int i = L; i <= R; i++)
{
// If (i - L) is a prime
if (segmentedSieve[i - L])
{
// Update cntPairs
cntPairs += i / 2;
}
}
return cntPairs;
}
// Driver Code
public static void Main()
{
int L = 1, R = 5;
Console.Write(countPairsWhoseSumPrimeL_R(L, R));
}
}
// This code is contributed by akhilsaini
4
时间复杂度: O((R − L + 1)*log(log(R))+ sqrt(R)*log(log(sqrt(R)))
辅助空间: O(R – L +1 + sqrt(R))