Value of k-th index of a series formed by append and insert MEX in middle

Given two integers, n and k. Initially we have a sequence consisting of a single number 1. We need to consider series formed after n steps. In each step, we append the sequence to itself and insert the MEX(minimum excluded)(>0) value of the sequence in the middle. Perform (n-1) steps. Finally, find the value of the k-th index of the resulting sequence.

Example:

Input : n = 3, k = 2.
Output: Initially, we have {1}, we have to perform 2 steps.
        1st step :  {1, 2, 1}, since MEX of {1} is 2.
        2nd step:   {1, 2, 1, 3, 1, 2, 1}, 
                     since MEX of {1, 2, 1} is 3.
        Value of 2nd Index = 2.

Input : n = 4, k = 8.
Output: Perform 3 steps.
        After second step, we have  {1, 2, 1, 3, 1, 2, 1}
        3rd step: {1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 
                               1, 2, 1}, since MEX = 4.
        Value of 8th index = 4.


A simple solution is to generate the series using given steps and store in an array. Finally, we return k-th element of the array.

An efficient solution is to use Binary Search. Observe that the middle element of our resulting sequence is n itself. Length of the sequence is 2n – 1, because lengths will be like (1, 3, 7, 15….2n -1). We use Binary search to solve this problem. As we know that the middle element of a sequence is the number of the step(from 1) performed on it.
In fact, every element in the sequence is a middle element at one or other step.
We start searching the element from step n and compare the middle index with ‘k’ if found we return n, else we decrease n by 1 and update our range of our search.
we repeat this step until the index is reached.

CPP

filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP program to fin k-th element after append
// and insert middle operations
#include <bits/stdc++.h>
using namespace std;
void findElement(int n, int k)
{
    int ans = n; // Middle element of the sequence
    int left = 1;
  
    // length of the resulting sequence.
    int right = pow(2, n) - 1; 
    while (1) {
        int mid = (left + right) / 2;
        if (k == mid) {
            cout << ans << endl;
            break;
        }
  
        // Updating the middle element of next sequence 
        ans--; 
  
        // Moving to the left side of the middle element.
        if (k < mid) 
            right = mid - 1; 
          
        // Moving to the right side of the middle element.
        else 
            left = mid + 1;         
    }
}
  
// Driver code
int main()
{
    int n = 4, k = 8;
    findElement(n, k);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to fin k-th element after append
// and insert middle operations
  
class GFG 
{
  
    static void findElement(int n, int k) 
    {
        // Middle element of the sequence
        int ans = n; 
        int left = 1;
  
        // length of the resulting sequence.
        int right = (int) (Math.pow(2, n) - 1);
        while (true)
        {
            int mid = (left + right) / 2;
            if (k == mid)
            {
                System.out.println(ans);
                break;
            }
  
            // Updating the middle element
            // of next sequence 
            ans--;
  
            // Moving to the left side of 
            // the middle element.
            if (k < mid) 
            {
                right = mid - 1;
            }
              
            // Moving to the right side of 
            // the middle element.
            else 
            {
                left = mid + 1;
            }
        }
    }
  
    // Driver code
    public static void main(String[] args) 
    {
        int n = 4, k = 8;
        findElement(n, k);
    }
  
}
  
// This code has been contributed by 29AjayKumar

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 code to find k-th element after append
# and insert middle operations
import math
  
def findElement(n , k):
    ans = n      # Middle element of the sequence
    left = 1
      
    # length of the resulting sequence.
    right = math.pow(2, n) - 1
    while 1:
        mid = int((left + right) / 2)
        if k == mid:
            print(ans)
            break
          
        # Updating the middle element of next sequence
        ans-=1
          
        # Moving to the left side of the middle element.
        if k < mid:
            right = mid - 1
          
        # Moving to the right side of the middle element.
        else:
            left = mid + 1
  
# Driver code
n = 4
k = 8
findElement(n, k)
  
# This code is contributed by "Sharad_Bhardwaj".

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to fin k-th element after append
// and insert middle operations
using System; 
  
class GFG 
{
  
    static void findElement(int n, int k) 
    {
        // Middle element of the sequence
        int ans = n; 
        int left = 1;
  
        // length of the resulting sequence.
        int right = (int) (Math.Pow(2, n) - 1);
        while (true)
        {
            int mid = (left + right) / 2;
            if (k == mid)
            {
                Console.WriteLine(ans);
                break;
            }
  
            // Updating the middle element
            // of next sequence 
            ans--;
  
            // Moving to the left side of 
            // the middle element.
            if (k < mid) 
            {
                right = mid - 1;
            }
              
            // Moving to the right side of 
            // the middle element.
            else
            {
                left = mid + 1;
            }
        }
    }
  
    // Driver code
    public static void Main() 
    {
        int n = 4, k = 8;
        findElement(n, k);
    }
  
}
  
/* This code contributed by PrinciRaj1992 */

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP program to fin k-th element
// after append and insert middle
// operations
  
function findElement($n, $k)
{
      
    // Middle element of the sequence
    $ans = $n
    $left = 1;
  
    // length of the resulting sequence.
    $right = pow(2, $n) - 1; 
    while (1) 
    {
        $mid = ($left + $right) / 2;
        if ($k ==$mid)
        {
            echo $ans ,"\n";
            break;
        }
  
        // Updating the middle element
        // of next sequence 
        $ans--; 
  
        // Moving to the left side of 
        // the middle element.
        if ($k < $id
            $right = $mid - 1; 
          
        // Moving to the right side
        // of the middle element.
        else
            $left = $mid + 1;     
    }
}
  
    // Driver code
    $n = 4;
    $k = 8;
    findElement($n, $k);
  
// This code is contributed by aj_36
?>

chevron_right



Output:

4

Time Complexity:O(log n)



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.