Skip to content
Related Articles

Related Articles

Improve Article

Find element position in given monotonic sequence

  • Difficulty Level : Medium
  • Last Updated : 06 Jun, 2021

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) = 12168587437017

Input: 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.

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++




// 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;
}

Python3




# 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

PHP




<?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
?>

Javascript




<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>
Output: 
23001

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :