📌  相关文章
📜  计算给定范围内的对,其总和是该范围内的素数

📅  最后修改于: 2021-04-30 02:45:10             🧑  作者: Mango

给定两个整数LR,则任务是从其总和是在范围[L,R]为素数的范围内[L,R]计数对的数目。

例子:

天真的方法:解决此问题的最简单方法是从[1,R ]范围内生成所有可能的对并针对每对,检查该对元素的和是否为[L,R]范围内的质数。或不。如果发现为真,则增加count 。最后,打印count的值。

时间复杂度:O(N 5/2)
辅助空间: O(1)

高效方法:为了优化上述方法,该思想基于以下观察结果:

请按照以下步骤解决问题:

  • 初始化一个变量,例如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))