Given a 2d array queries[][] of size n, where each query queries[i] contain 2 elements [l, r], your task is to find the count of number of primes in inclusive range [l, r]
Examples:
Input: queries[][] = [ [1, 10], [5, 10], [11, 20] ]
Output: 4 2 4
Explanation: For query 1, number of primes in range [1, 10] are 4 (2, 3, 5, 7).
For query 2, number of primes in range [5, 10] are 2 (5, 7).
For query 3, number of primes in range [11, 20] are 4 (11, 13, 17, 19).
[Naive Approach] - O(n * (r - l + 1) * r1/2) Time and O(1) Space
The idea is to answer each query by iterating through every integer in the specified range [L, R], using a primality check to identify primes, and accumulating the total number of primes found.
Please note that r1/2 is an upper bound for checking prime status of numbers from l to r.
Follow the below given steps:
- Implement a function
isPrime(n)that returnsfalseifn ≤ 1, otherwise checks divisibility from2up to √n and returnsfalseon the first divisor found, ortrueif none are found. - In
solveQueries, create an empty listresultsto hold the prime counts for each query. - For each query
[l, r]in the list of queries:- Initialize
count = 0. - For
jfromltorinclusive, callisPrime(j); if it returnstrue, incrementcount. - After the loop, append
counttoresults.
- Initialize
- Return
resultscontaining the prime counts for all queries.
Below is given the implementation:
#include <bits/stdc++.h>
using namespace std;
// Function to check if a number is prime
bool isPrime(int n) {
if(n <= 1) return false;
for(int i = 2; i * i <= n; i++) {
if(n % i == 0) return false;
}
return true;
}
// function to solve the queries
vector<int> solveQueries(vector<vector<int>>& queries) {
int n = queries.size();
// to store the results
vector<int> results;
for(int i = 0; i < n; i++) {
int l = queries[i][0];
int r = queries[i][1];
int count = 0;
// Count the prime numbers in the range [l, r]
for(int j = l; j <= r; j++) {
if(isPrime(j)) {
count++;
}
}
// Store the result for this query
results.push_back(count);
}
return results;
}
int main() {
vector<vector<int>> queries = { {1, 10}, {5, 10}, {11, 20} };
vector<int> res = solveQueries(queries);
for(auto i: res) {
cout << i << " ";
}
return 0;
}
import java.util.*;
class GfG {
public static boolean isPrime(int n) {
if(n <= 1) return false;
for(int i = 2; i * i <= n; i++) {
if(n % i == 0) return false;
}
return true;
}
public static ArrayList<Integer> solveQueries(ArrayList<ArrayList<Integer>> queries) {
int n = queries.size();
// to store the results
ArrayList<Integer> results = new ArrayList<>();
for (int i = 0; i < n; i++) {
int l = queries.get(i).get(0);
int r = queries.get(i).get(1);
int count = 0;
// Count the prime numbers in the range [l, r]
for (int j = l; j <= r; j++) {
if (isPrime(j)) {
count++;
}
}
// Store the result for this query
results.add(count);
}
return results;
}
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> queries = new ArrayList<>(Arrays.asList(
new ArrayList<>(Arrays.asList(1, 10)),
new ArrayList<>(Arrays.asList(5, 10)),
new ArrayList<>(Arrays.asList(11, 20))
));
ArrayList<Integer> res = solveQueries(queries);
for (int i : res) {
System.out.print(i + " ");
}
}
}
def isPrime(n):
if n <= 1:
return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False
return True
def solveQueries(queries):
n = len(queries)
# to store the results
results = []
for i in range(n):
l = queries[i][0]
r = queries[i][1]
count = 0
# Count the prime numbers in the range [l, r]
for j in range(l, r + 1):
if isPrime(j):
count += 1
# Store the result for this query
results.append(count)
return results
if __name__ == "__main__":
queries = [[1, 10], [5, 10], [11, 20]]
res = solveQueries(queries)
for i in res:
print(i, end=" ")
using System;
using System.Collections.Generic;
class GfG {
public static bool isPrime(int n) {
if(n <= 1) return false;
for(int i = 2; i * i <= n; i++) {
if(n % i == 0) return false;
}
return true;
}
public static List<int> solveQueries(List<List<int>> queries) {
int n = queries.Count;
// to store the results
List<int> results = new List<int>();
for (int i = 0; i < n; i++) {
int l = queries[i][0];
int r = queries[i][1];
int count = 0;
// Count the prime numbers in the range [l, r]
for (int j = l; j <= r; j++) {
if (isPrime(j)) {
count++;
}
}
// Store the result for this query
results.Add(count);
}
return results;
}
public static void Main() {
List<List<int>> queries = new List<List<int>> {
new List<int> {1, 10},
new List<int> {5, 10},
new List<int> {11, 20}
};
List<int> res = solveQueries(queries);
foreach (var i in res) {
Console.Write(i + " ");
}
}
}
function isPrime(n) {
if(n <= 1) return false;
for (let i = 2; i * i <= n; i++) {
if (n % i == 0) return false;
}
return true;
}
function solveQueries(queries) {
let n = queries.length;
// to store the results
let results = [];
for (let i = 0; i < n; i++) {
let l = queries[i][0];
let r = queries[i][1];
let count = 0;
// Count the prime numbers in the range [l, r]
for (let j = l; j <= r; j++) {
if (isPrime(j)) {
count++;
}
}
// Store the result for this query
results.push(count);
}
return results;
}
let queries = [[1, 10], [5, 10], [11, 20]];
let res = solveQueries(queries);
for (let i of res) {
process.stdout.write(i + " ");
}
Output
4 2 4
[Expected Approach] - Using Sieve of Eratosthenes - O(maxR * log (log maxR))) Time and O(n) Space
The idea is to precompute all primes up to the maximum query endpoint using the Sieve of Eratosthenes, then build a prefix-sum array of prime counts so that each range query can be answered in O(1) time by taking the difference of two prefix values.
Here
maxRthe maximum value in queries.
Follow the below given steps:
- Determine the largest right endpoint
maxRamong all queries. - Run the Sieve of Eratosthenes up to
maxRto create a boolean arrayprimes[]whereprimes[i]is 1 ifiis prime, 0 otherwise. - Convert
primes[]into a prefix-sum array so thatprimes[i]holds the count of primes from 0 toi. - For each query
[l, r], compute the answer asprimes[r] - primes[l - 1]and store it in the results list. - Return the list of results for all queries.
Below is given the implementation:
#include <bits/stdc++.h>
using namespace std;
// Function to find all prime numbers
// up to n using Sieve of Eratosthenes
vector<int> findPrimes(int n) {
vector<int> primes(n + 1, 1);
// 0 and 1 are not prime numbers
primes[0] = primes[1] = 0;
for(int i = 2; i * i <= n; i++) {
if(primes[i]) {
for(int j = i * i; j <= n; j += i) {
primes[j] = 0;
}
}
}
return primes;
}
// function to solve the queries
vector<int> solveQueries(vector<vector<int>>& queries) {
int n = queries.size();
// to store the res
vector<int> res;
// Find the maximum value of r in the queries
int maxR = 0;
for(int i = 0; i < n; i++) {
maxR = max(maxR, queries[i][1]);
}
// Get the prime numbers up to maxR
vector<int> primes = findPrimes(maxR);
// Precompute the prefix sum of prime counts
for(int i = 1; i <= maxR; i++) {
primes[i] += primes[i - 1];
}
for(int i = 0; i < n; i++) {
int l = queries[i][0];
int r = queries[i][1];
// Count the prime numbers in the range [l, r]
int count = primes[r] - primes[l - 1];
// Store the result for this query
res.push_back(count);
}
return res;
}
int main() {
vector<vector<int>> queries = { {1, 10}, {5, 10}, {11, 20} };
vector<int> res = solveQueries(queries);
for(auto i: res) {
cout << i << " ";
}
return 0;
}
import java.util.*;
class GfG {
public static ArrayList<Integer> findPrimes(int n) {
ArrayList<Integer> primes = new ArrayList<>(Collections.nCopies(n + 1, 1));
// 0 and 1 are not prime numbers
primes.set(0, 0);
primes.set(1, 0);
for (int i = 2; i * i <= n; i++) {
if (primes.get(i) == 1) {
for (int j = i * i; j <= n; j += i) {
primes.set(j, 0);
}
}
}
return primes;
}
public static ArrayList<Integer> solveQueries(ArrayList<ArrayList<Integer>> queries) {
int n = queries.size();
// to store the res
ArrayList<Integer> res = new ArrayList<>();
// Find the maximum value of r in the queries
int maxR = 0;
for (int i = 0; i < n; i++) {
maxR = Math.max(maxR, queries.get(i).get(1));
}
// Get the prime numbers up to maxR
ArrayList<Integer> primes = findPrimes(maxR);
// Precompute the prefix sum of prime counts
for (int i = 1; i <= maxR; i++) {
primes.set(i, primes.get(i) + primes.get(i - 1));
}
for (int i = 0; i < n; i++) {
int l = queries.get(i).get(0);
int r = queries.get(i).get(1);
// Count the prime numbers in the range [l, r]
int count = primes.get(r) - primes.get(l - 1);
// Store the result for this query
res.add(count);
}
return res;
}
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> queries = new ArrayList<>();
queries.add(new ArrayList<>(Arrays.asList(1, 10)));
queries.add(new ArrayList<>(Arrays.asList(5, 10)));
queries.add(new ArrayList<>(Arrays.asList(11, 20)));
ArrayList<Integer> res = solveQueries(queries);
for (int i : res) {
System.out.print(i + " ");
}
}
}
def findPrimes(n):
primes = [1] * (n + 1)
# 0 and 1 are not prime numbers
primes[0] = primes[1] = 0
for i in range(2, int(n**0.5) + 1):
if primes[i]:
for j in range(i * i, n + 1, i):
primes[j] = 0
return primes
def solveQueries(queries):
n = len(queries)
# to store the res
res = []
# Find the maximum value of r in the queries
maxR = 0
for i in range(n):
maxR = max(maxR, queries[i][1])
# Get the prime numbers up to maxR
primes = findPrimes(maxR)
# Precompute the prefix sum of prime counts
for i in range(1, maxR + 1):
primes[i] += primes[i - 1]
for i in range(n):
l = queries[i][0]
r = queries[i][1]
# Count the prime numbers in the range [l, r]
count = primes[r] - primes[l - 1]
# Store the result for this query
res.append(count)
return res
if __name__ == "__main__":
queries = [[1, 10], [5, 10], [11, 20]]
res = solveQueries(queries)
for i in res:
print(i, end=" ")
using System;
using System.Collections.Generic;
using System.Linq;
class GfG {
public static List<int> findPrimes(int n) {
List<int> primes = Enumerable.Repeat(1, n + 1).ToList();
// 0 and 1 are not prime numbers
primes[0] = 0;
primes[1] = 0;
for (int i = 2; i * i <= n; i++) {
if (primes[i] == 1) {
for (int j = i * i; j <= n; j += i) {
primes[j] = 0;
}
}
}
return primes;
}
public static List<int> solveQueries(List<List<int>> queries) {
int n = queries.Count;
// to store the res
List<int> res = new List<int>();
// Find the maximum value of r in the queries
int maxR = 0;
for (int i = 0; i < n; i++) {
maxR = Math.Max(maxR, queries[i][1]);
}
// Get the prime numbers up to maxR
List<int> primes = findPrimes(maxR);
// Precompute the prefix sum of prime counts
for (int i = 1; i <= maxR; i++) {
primes[i] += primes[i - 1];
}
for (int i = 0; i < n; i++) {
int l = queries[i][0];
int r = queries[i][1];
// Count the prime numbers in the range [l, r]
int count = primes[r] - primes[l - 1];
// Store the result for this query
res.Add(count);
}
return res;
}
public static void Main() {
List<List<int>> queries = new List<List<int>> {
new List<int> {1, 10},
new List<int> {5, 10},
new List<int> {11, 20}
};
List<int> res = solveQueries(queries);
foreach (var i in res) {
Console.Write(i + " ");
}
}
}
function findPrimes(n) {
let primes = Array(n + 1).fill(1);
// 0 and 1 are not prime numbers
primes[0] = primes[1] = 0;
for (let i = 2; i * i <= n; i++) {
if (primes[i]) {
for (let j = i * i; j <= n; j += i) {
primes[j] = 0;
}
}
}
return primes;
}
function solveQueries(queries) {
let n = queries.length;
// to store the res
let res = [];
// Find the maximum value of r in the queries
let maxR = 0;
for (let i = 0; i < n; i++) {
maxR = Math.max(maxR, queries[i][1]);
}
// Get the prime numbers up to maxR
let primes = findPrimes(maxR);
// Precompute the prefix sum of prime counts
for (let i = 1; i <= maxR; i++) {
primes[i] += primes[i - 1];
}
for (let i = 0; i < n; i++) {
let l = queries[i][0];
let r = queries[i][1];
// Count the prime numbers in the range [l, r]
let count = primes[r] - primes[l - 1];
// Store the result for this query
res.push(count);
}
return res;
}
let queries = [[1, 10], [5, 10], [11, 20]];
let res = solveQueries(queries);
for (let i of res) {
process.stdout.write(i + " ");
}
Output
4 2 4