Related Articles

Related Articles

Count pairs from a given range whose sum is a Prime Number in that range
  • Last Updated : 18 Nov, 2020

Given two integers L and R, the task is to count the number of pairs from the range [L, R] whose sum is a prime number in the range [L, R].

Examples:

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

Naive Approach: The simplest approach to solve this problem is to generate all possible pairs from the range [1, R] and for each pair, check if the sum of elements of the pair is a prime number in the range [L, R] or not. If found to be true, then increment count. Finally, print the value of count.



Time Complexity: O(N5 / 2)
Auxiliary Space: O(1)

Efficient Approach: To optimize the above approach the idea is based on the following observations:

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

Follow the steps below to solve the problem:

  • Initialize a variable say, cntPairs to store the count of pairs such that the sum of elements of the pair is a prime number and in the range [L, R].
  • Initialize an array say segmentedSieve[] to store all the prime numbers in the range [L, R] using Sieve of Eratosthenes.
  • Traverse the segment 
    tedSieve[] using the variable i and check if i is a prime number or not. If found to be true then increment the value of cntPairs by (i / 2).
  • Finally, print the value of cntPairs.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to implement
// the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find all prime numbers in range
// [1, lmt] using sieve of Eratosthenes
void simpleSieve(int lmt, vector<int>& 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<bool> 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<int> 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<bool> 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<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
int main()
{
    int L = 1, R = 5;
    cout << countPairsWhoseSumPrimeL_R(L, R);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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<Integer> simpleSieve(int lmt,
       ArrayList<Integer> 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<Integer> prime = new ArrayList<Integer>();
 
    // 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

chevron_right


Python

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


Output: 

4



 

Time Complexity: O((R − L + 1) * log⁡(log⁡(R)) + sqrt(R) * log⁡(log⁡(sqrt(R))) 
Auxiliary Space: O(R – L + 1 + sqrt(R))

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up
Recommended Articles
Page :