Given an integer k and a monotonic increasing sequence:
f(n) = an + bn [log2(n)] + cn^3 where (a = 1, 2, 3, …), (b = 1, 2, 3, …), (c = 0, 1, 2, 3, …)
Here, [log2(n)] means, taking the log to the base 2 and round the value down Thus,
if n = 1, the value is 0.
if n = 2-3, the value is 1.
if n = 4-7, the value is 2.
if n = 8-15, the value is 3.
The task is to find the value n such that f(n) = k, if k doesn’t belong to the sequence then print 0.
Note: Values are in such a way that they can be expressed in 64 bits and the three integers a, b and c do not exceed 100.
Examples:
Input: a = 2, b = 1, c = 1, k = 12168587437017
Output: 23001
f(23001) = 12168587437017Input: a = 7, b = 3, c = 0, k = 119753085330
Output: 1234567890
Naive Approach: Given values of a, b, c, find values of f(n) for every value of n and compare it.
Time Complexity: O(n)
Space Complexity: O(1)
Efficient Approach: Use Binary Search, choose n = (min + max) / 2 where min and max are the minimum and maximum values possible for n then,
- If f(n) < k then increment n.
- If f(n) > k then decrement n.
- If f(n) = k then n is the required answer.
- Repeat the above steps until the required value is found or it is not possible in the sequence.
Below is the implementation of the above approach:
// C++ implementation of the approach #include <iostream> #include <math.h> #define SMALL_N 1000000 #define LARGE_N 1000000000000000 using namespace std;
// Function to return the value of f(n) for given values of a, b, c, n long long func( long long a, long long b, long long c, long long n)
{ long long res = a * n;
long long logVlaue = floor (log2(n));
res += b * n * logVlaue;
res += c * (n * n * n);
return res;
} long long getPositionInSeries( long long a, long long b,
long long c, long long k)
{ long long start = 1, end = SMALL_N;
// if c is 0, then value of n can be in order of 10^15.
// if c!=0, then n^3 value has to be in order of 10^18
// so maximum value of n can be 10^6.
if (c == 0) {
end = LARGE_N;
}
long long ans = 0;
// for efficient searching, use binary search.
while (start <= end) {
long long mid = (start + end) / 2;
long long val = func(a, b, c, mid);
if (val == k) {
ans = mid;
break ;
}
else if (val > k) {
end = mid - 1;
}
else {
start = mid + 1;
}
}
return ans;
} // Driver code int main()
{ long long a = 2, b = 1, c = 1;
long long k = 12168587437017;
cout << getPositionInSeries(a, b, c, k);
return 0;
} |
// Java implementation of the approach import java.util.*;
class GFG {
static long SMALL_N = 1000000 ;
static Long LARGE_N = Long.parseUnsignedLong( "1000000000000000" );
// Function to return the value of f(n) for given values
// of a, b, c, n
static long func( long a, long b, long c, long n)
{
long res = a * n;
long logVlaue = ( long )(Math.log(n) / Math.log( 2 ));
res += b * n * logVlaue;
res += c * (n * n * n);
return res;
}
static long getPositionInSeries( long a, long b, long c,
long k)
{
long start = 1 , end = SMALL_N;
// if c is 0, then value of n can be in order of
// 10^15. if c!=0, then n^3 value has to be in order
// of 10^18 so maximum value of n can be 10^6.
if (c == 0 ) {
end = LARGE_N;
}
long ans = 0 ;
// for efficient searching, use binary search.
while (start <= end) {
long mid = (start + end) / 2 ;
long val = func(a, b, c, mid);
if (val == k) {
ans = mid;
break ;
}
else if (val > k) {
end = mid - 1 ;
}
else {
start = mid + 1 ;
}
}
return ans;
}
// Driver code
public static void main(String[] args)
{
long a = 2 , b = 1 , c = 1 ;
Long k = Long.parseUnsignedLong( "12168587437017" );
System.out.println(getPositionInSeries(a, b, c, k));
}
} // This code is contributed by phasing17 |
# Python 3 implementation of the approach from math import log2, floor
SMALL_N = 1000000
LARGE_N = 1000000000000000
# Function to return the value of f(n) # for given values of a, b, c, n def func(a, b, c, n) :
res = a * n
logVlaue = floor(log2(n))
res + = b * n * logVlaue
res + = c * (n * n * n)
return res
def getPositionInSeries(a, b, c, k) :
start = 1
end = SMALL_N
# if c is 0, then value of n
# can be in order of 10^15.
# if c!=0, then n^3 value has
# to be in order of 10^18
# so maximum value of n can be 10^6.
if (c = = 0 ) :
end = LARGE_N
ans = 0
# for efficient searching,
# use binary search.
while (start < = end) :
mid = (start + end) / / 2
val = func(a, b, c, mid)
if (val = = k) :
ans = mid
break
elif (val > k) :
end = mid - 1
else :
start = mid + 1
return ans;
# Driver code if __name__ = = "__main__" :
a = 2
b = 1
c = 1
k = 12168587437017
print (getPositionInSeries(a, b, c, k))
# This code is contributed by Ryuga |
// C# implementation of the approach using System;
using System.Collections.Generic;
class GFG {
static long SMALL_N = 1000000;
static long LARGE_N = 1000000000000000;
// Function to return the value of f(n) for given values
// of a, b, c, n
static long func( long a, long b, long c, long n)
{
long res = a * n;
long logVlaue = ( long )(Math.Log(n) / Math.Log(2));
res += b * n * logVlaue;
res += c * (n * n * n);
return res;
}
static long getPositionInSeries( long a, long b, long c,
long k)
{
long start = 1, end = SMALL_N;
// if c is 0, then value of n can be in order of
// 10^15. if c!=0, then n^3 value has to be in order
// of 10^18 so maximum value of n can be 10^6.
if (c == 0) {
end = LARGE_N;
}
long ans = 0;
// for efficient searching, use binary search.
while (start <= end) {
long mid = (start + end) / 2;
long val = func(a, b, c, mid);
if (val == k) {
ans = mid;
break ;
}
else if (val > k) {
end = mid - 1;
}
else {
start = mid + 1;
}
}
return ans;
}
// Driver code
public static void Main( string [] args)
{
long a = 2, b = 1, c = 1;
long k = 12168587437017;
Console.WriteLine(getPositionInSeries(a, b, c, k));
}
} // This code is contributed by phasing17 |
<?php // PHP implementation of the approach // from math import log2, floor $SMALL_N = 1000000;
$LARGE_N = 1000000000000000;
// Function to return the value of f(n) // for given values of a, b, c, n function func( $a , $b , $c , $n )
{ $res = $a * $n ;
$logVlaue = floor (log( $n , 2));
$res += $b * $n * $logVlaue ;
$res += $c * ( $n * $n * $n );
return $res ;
} function getPositionInSeries( $a , $b , $c , $k )
{ global $SMALL_N , $LARGE_N ;
$start = 1;
$end = $SMALL_N ;
// if c is 0, then value of n
// can be in order of 10^15.
// if c!=0, then n^3 value has
// to be in order of 10^18
// so maximum value of n can be 10^6.
if ( $c == 0)
$end = $LARGE_N ;
$ans = 0;
// for efficient searching,
// use binary search.
while ( $start <= $end )
{
$mid = (int)(( $start + $end ) / 2);
$val = func( $a , $b , $c , $mid ) ;
if ( $val == $k )
{
$ans = $mid ;
break ;
}
else if ( $val > $k )
$end = $mid - 1;
else
$start = $mid + 1;
}
return $ans ;
} // Driver code $a = 2;
$b = 1;
$c = 1;
$k = 12168587437017;
print (getPositionInSeries( $a , $b , $c , $k ));
// This code is contributed by mits ?> |
<script> // Javascript implementation of the approach const SMALL_N = 1000000; const LARGE_N = 1000000000000000; // Function to return the value of f(n) // for given values of a, b, c, n function func(a, b, c, n)
{ let res = a * n;
let logVlaue = Math.floor(Math.log(n) /
Math.log(2));
res += b * n * logVlaue;
res += c * (n * n * n);
return res;
} function getPositionInSeries(a, b, c, k)
{ let start = 1, end = SMALL_N;
// If c is 0, then value of n can be
// in order of 10^15. If c!=0, then
// n^3 value has to be in order of 10^18
// so maximum value of n can be 10^6.
if (c == 0)
{
end = LARGE_N;
}
let ans = 0;
// For efficient searching, use binary search.
while (start <= end)
{
let mid = parseInt((start + end) / 2);
let val = func(a, b, c, mid);
if (val == k)
{
ans = mid;
break ;
}
else if (val > k)
{
end = mid - 1;
}
else
{
start = mid + 1;
}
}
return ans;
} // Driver code let a = 2, b = 1, c = 1; let k = 12168587437017; document.write(getPositionInSeries(a, b, c, k)); // This code is contributed by souravmahato348 </script> |
23001
Time Complexity: O(log n), since it’s a binary search where each time the elements are reduced to half.
Auxiliary Space: O(1), since no extra space has been taken.