Given two positive integers N and K, the task is to count all the numbers that satisfy the following conditions:
If the number is num,
- num ? N.
- abs(num – count) ? K where count is the count of primes upto num.
Examples:
Input: N = 10, K = 3
Output: 5
6, 7, 8, 9 and 10 are the valid numbers. For 6, the difference between 6 and prime numbers upto 6 (2, 3, 5) is 3 i.e. 6 – 3 = 3. For 7, 8, 9 and 10 the differences are 3, 4, 5 and 6 respectively which are ? K.
Input: N = 30, K = 13
Output: 10
Prerequisite: Binary Search
Approach: Observe that the function which is the difference of the number and count of prime numbers upto that number is a monotonically increasing function for a particular K. Also, if a number X is a valid number then X + 1 will also be a valid number.
Proof :
Let the function Ci denotes the count of prime numbers upto number i. Now,
for the number X + 1 the difference is X + 1 – CX + 1 which is greater than
or equal to the difference X – CX for the number X, i.e. (X + 1 – CX + 1) ? (X – CX).
Thus, if (X – CX) ? S, then (X + 1 – CX + 1) ? S.
Hence, we can use binary search to find the minimum valid number X and all the numbers from X to N will be valid numbers. So, the answer would be N – X + 1.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
const int MAX = 1000001;
int primeUpto[MAX];
void SieveOfEratosthenes()
{
bool isPrime[MAX];
memset (isPrime, 1, sizeof (isPrime));
isPrime[0] = isPrime[1] = 0;
for ( int i = 2; i * i < MAX; i++) {
if (isPrime[i]) {
for ( int j = i * 2; j < MAX; j += i)
isPrime[j] = 0;
}
}
for ( int i = 1; i < MAX; i++) {
primeUpto[i] = primeUpto[i - 1];
if (isPrime[i])
primeUpto[i]++;
}
}
int countOfNumbers( int N, int K)
{
SieveOfEratosthenes();
int low = 1, high = N, ans = 0;
while (low <= high) {
int mid = (low + high) >> 1;
if (mid - primeUpto[mid] >= K) {
ans = mid;
high = mid - 1;
}
else
low = mid + 1;
}
return (ans ? N - ans + 1 : 0);
}
int main()
{
int N = 10, K = 3;
cout << countOfNumbers(N, K);
}
|
Java
public class GFG{
static final int MAX = 1000001 ;
static int primeUpto[] = new int [MAX];
static void SieveOfEratosthenes()
{
int isPrime[] = new int [MAX];
for ( int i= 0 ; i < MAX ; i++ )
isPrime[i] = 1 ;
isPrime[ 0 ] = isPrime[ 1 ] = 0 ;
for ( int i = 2 ; i * i < MAX; i++) {
if (isPrime[i] == 1 ) {
for ( int j = i * 2 ; j < MAX; j += i)
isPrime[j] = 0 ;
}
}
for ( int i = 1 ; i < MAX; i++) {
primeUpto[i] = primeUpto[i - 1 ];
if (isPrime[i] == 1 )
primeUpto[i]++;
}
}
static int countOfNumbers( int N, int K)
{
SieveOfEratosthenes();
int low = 1 , high = N, ans = 0 ;
while (low <= high) {
int mid = (low + high) >> 1 ;
if (mid - primeUpto[mid] >= K) {
ans = mid;
high = mid - 1 ;
}
else
low = mid + 1 ;
}
ans = ans != 0 ? N - ans + 1 : 0 ;
return ans ;
}
public static void main(String []args)
{
int N = 10 , K = 3 ;
System.out.println(countOfNumbers(N, K)) ;
}
}
|
Python3
MAX = 1000001
MAX_sqrt = MAX * * ( 0.5 )
primeUpto = [ 0 ] * ( MAX )
def SieveOfEratosthenes():
isPrime = [ 1 ] * ( MAX )
isPrime[ 0 ], isPrime[ 1 ] = 0 , 0
for i in range ( 2 , int (MAX_sqrt)):
if isPrime[i] = = 1 :
for j in range (i * 2 , MAX , i):
isPrime[j] = 0
for i in range ( 1 , MAX ):
primeUpto[i] = primeUpto[i - 1 ]
if isPrime[i] = = 1 :
primeUpto[i] + = 1
def countOfNumbers(N, K):
SieveOfEratosthenes()
low, high, ans = 1 , N, 0
while low < = high:
mid = (low + high) >> 1
if mid - primeUpto[mid] > = K:
ans = mid
high = mid - 1
else :
low = mid + 1
return (N - ans + 1 ) if ans else 0
if __name__ = = "__main__" :
N, K = 10 , 3
print (countOfNumbers(N, K))
|
C#
using System;
public class GFG{
static int MAX = 1000001;
static int []primeUpto = new int [MAX];
static void SieveOfEratosthenes()
{
int []isPrime = new int [MAX];
for ( int i=0; i < MAX ; i++ )
isPrime[i] = 1;
isPrime[0] = isPrime[1] = 0;
for ( int i = 2; i * i < MAX; i++) {
if (isPrime[i] == 1) {
for ( int j = i * 2; j < MAX; j += i)
isPrime[j] = 0;
}
}
for ( int i = 1; i < MAX; i++) {
primeUpto[i] = primeUpto[i - 1];
if (isPrime[i] == 1)
primeUpto[i]++;
}
}
static int countOfNumbers( int N, int K)
{
SieveOfEratosthenes();
int low = 1, high = N, ans = 0;
while (low <= high) {
int mid = (low + high) >> 1;
if (mid - primeUpto[mid] >= K) {
ans = mid;
high = mid - 1;
}
else
low = mid + 1;
}
ans = ans != 0 ? N - ans + 1 : 0 ;
return ans ;
}
public static void Main()
{
int N = 10, K = 3;
Console.WriteLine(countOfNumbers(N, K)) ;
}
}
|
PHP
<?php
$MAX = 100001;
$primeUpto = array_fill (0, $MAX , 0);
function SieveOfEratosthenes()
{
global $MAX , $primeUpto ;
$isPrime = array_fill (0, $MAX , true);
$isPrime [0] = $isPrime [1] = false;
for ( $i = 2; $i * $i < $MAX ; $i ++)
{
if ( $isPrime [ $i ])
{
for ( $j = $i * 2; $j < $MAX ; $j += $i )
$isPrime [ $j ] = false;
}
}
for ( $i = 1; $i < $MAX ; $i ++)
{
$primeUpto [ $i ] = $primeUpto [ $i - 1];
if ( $isPrime [ $i ])
$primeUpto [ $i ]++;
}
}
function countOfNumbers( $N , $K )
{
SieveOfEratosthenes();
global $primeUpto ;
$low = 1;
$high = $N ;
$ans = 0;
while ( $low <= $high )
{
$mid = ( $low + $high ) >> 1;
if ( $mid - $primeUpto [ $mid ] >= $K )
{
$ans = $mid ;
$high = $mid - 1;
}
else
$low = $mid + 1;
}
return ( $ans ? $N - $ans + 1 : 0);
}
$N = 10;
$K = 3;
echo countOfNumbers( $N , $K );
?>
|
Javascript
<script>
var MAX = 1000001;
var primeUpto = Array(MAX).fill(0);
function SieveOfEratosthenes()
{
var isPrime = Array(MAX).fill(1);
isPrime[0] = isPrime[1] = 0;
for ( var i = 2; i * i < MAX; i++) {
if (isPrime[i]) {
for ( var j = i * 2; j < MAX; j += i)
isPrime[j] = 0;
}
}
for ( var i = 1; i < MAX; i++) {
primeUpto[i] = primeUpto[i - 1];
if (isPrime[i])
primeUpto[i]++;
}
}
function countOfNumbers(N, K)
{
SieveOfEratosthenes();
var low = 1, high = N, ans = 0;
while (low <= high) {
var mid = (low + high) >> 1;
if (mid - primeUpto[mid] >= K) {
ans = mid;
high = mid - 1;
}
else
low = mid + 1;
}
return (ans ? N - ans + 1 : 0);
}
var N = 10, K = 3;
document.write( countOfNumbers(N, K));
</script>
|
Time Complexity: O(MAX*log(log(MAX)))
Auxiliary Space: O(MAX)