Count of numbers whose difference with Fibonacci count upto them is atleast K
Prerequisites: Binary Search
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 fibonacci numbers upto num.
Examples:
Input: N = 10, K = 3
Output: 2
Explanation:
9 and 10 are the valid numbers which satisfy the given conditions.
For 9, the difference between 9 and fibonacci numbers upto 9 (0, 1, 2, 3, 5, 8) is i.e. 9 – 6 = 3.
For 10, the difference between 9 and fibonacci numbers upto 10 (0, 1, 2, 3, 5, 8) is i.e. 10 – 6 = 4.
Input: N = 30, K = 7
Output: 11
Observation: On observing carefully, the function which is the difference of the number and count of fibonacci 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 fibonacci 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.
Approach: Therefore, from the above observation, the idea is to use hashing to precompute and store the Fibonacci nodes up to the maximum value and create a prefix array using the prefix sum array concept where every index stores the number of Fibonacci numbers less than ‘i’ to make checking easy and efficient (in O(1) time).
Now, we can use binary search to find the minimum valid number X, as all the numbers in range [X, N] are valid. Therefore, 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 = 1000005;
int fibUpto[MAX + 1];
void compute( int sz)
{
bool isFib[sz + 1];
memset (isFib, false , sizeof (isFib));
int prev = 0, curr = 1;
isFib[prev] = isFib[curr] = true ;
while (curr <= sz) {
int temp = curr + prev;
isFib[temp] = true ;
prev = curr;
curr = temp;
}
fibUpto[0] = 1;
for ( int i = 1; i <= sz; i++) {
fibUpto[i] = fibUpto[i - 1];
if (isFib[i])
fibUpto[i]++;
}
}
int countOfNumbers( int N, int K)
{
compute(N);
int low = 1, high = N, ans = 0;
while (low <= high) {
int mid = (low + high) >> 1;
if (mid - fibUpto[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
import java.util.*;
class GFG{
static int MAX = 1000005 ;
static int []fibUpto = new int [MAX + 1 ];
static void compute( int sz)
{
boolean []isFib = new boolean [sz + 1 ];
int prev = 0 , curr = 1 ;
isFib[prev] = isFib[curr] = true ;
while (curr <= sz) {
int temp = curr + prev;
if (temp <= sz)
isFib[temp] = true ;
prev = curr;
curr = temp;
}
fibUpto[ 0 ] = 1 ;
for ( int i = 1 ; i <= sz; i++) {
fibUpto[i] = fibUpto[i - 1 ];
if (isFib[i])
fibUpto[i]++;
}
}
static int countOfNumbers( int N, int K)
{
compute(N);
int low = 1 , high = N, ans = 0 ;
while (low <= high) {
int mid = (low + high) >> 1 ;
if (mid - fibUpto[mid] >= K) {
ans = mid;
high = mid - 1 ;
}
else
low = mid + 1 ;
}
return (ans> 0 ? N - ans + 1 : 0 );
}
public static void main(String[] args)
{
int N = 10 , K = 3 ;
System.out.print(countOfNumbers(N, K));
}
}
|
Python3
MAX = 1000005
fibUpto = [ 0 ] * ( MAX + 1 )
def compute(sz):
isFib = [ False ] * (sz + 1 )
prev = 0
curr = 1
isFib[prev] = True
isFib[curr] = True
while (curr < = sz):
temp = curr + prev
if (temp< = sz):
isFib[temp] = True
prev = curr
curr = temp
fibUpto[ 0 ] = 1
for i in range ( 1 ,sz + 1 ):
fibUpto[i] = fibUpto[i - 1 ]
if (isFib[i]):
fibUpto[i] + = 1
def countOfNumbers(N, K):
compute(N)
low , high, ans = 1 , N, 0
while (low < = high):
mid = (low + high) >> 1
if (mid - fibUpto[mid] > = K):
ans = mid
high = mid - 1
else :
low = mid + 1
if (ans):
return (N - ans + 1 )
return 0
if __name__ = = "__main__" :
N = 10
K = 3
print (countOfNumbers(N, K))
|
C#
using System;
class GFG{
static int MAX = 1000005;
static int []fibUpto = new int [MAX + 1];
static void compute( int sz)
{
bool []isFib = new bool [sz + 1];
int prev = 0, curr = 1;
isFib[prev] = isFib[curr] = true ;
while (curr <= sz) {
int temp = curr + prev;
if (temp <= sz)
isFib[temp] = true ;
prev = curr;
curr = temp;
}
fibUpto[0] = 1;
for ( int i = 1; i <= sz; i++) {
fibUpto[i] = fibUpto[i - 1];
if (isFib[i])
fibUpto[i]++;
}
}
static int countOfNumbers( int N, int K)
{
compute(N);
int low = 1, high = N, ans = 0;
while (low <= high) {
int mid = (low + high) >> 1;
if (mid - fibUpto[mid] >= K) {
ans = mid;
high = mid - 1;
}
else
low = mid + 1;
}
return (ans>0 ? N - ans + 1 : 0);
}
public static void Main()
{
int N = 10, K = 3;
Console.WriteLine(countOfNumbers(N, K));
}
}
|
Javascript
<script>
let MAX = 1000005;
let fibUpto = new Array(MAX+1);
function compute(sz)
{
let isFib = new Array(sz + 1);
let prev = 0, curr = 1;
isFib[prev] = isFib[curr] = true ;
while (curr <= sz) {
let temp = curr + prev;
if (temp <= sz)
isFib[temp] = true ;
prev = curr;
curr = temp;
}
fibUpto[0] = 1;
for (let i = 1; i <= sz; i++) {
fibUpto[i] = fibUpto[i - 1];
if (isFib[i])
fibUpto[i]++;
}
}
function countOfNumbers(N,K)
{
compute(N);
let low = 1, high = N, ans = 0;
while (low <= high) {
let mid = (low + high) >> 1;
if (mid - fibUpto[mid] >= K) {
ans = mid;
high = mid - 1;
}
else
low = mid + 1;
}
return (ans>0 ? N - ans + 1 : 0);
}
let N = 10, K = 3;
document.write(countOfNumbers(N, K));
</script>
|
Last Updated :
02 Jun, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...