First element greater than or equal to X in prefix sum of N numbers using Binary Lifting in C++


In this problem, we are given an array arr[] consisting of N numbers and an integer value x. Our task is to create a program for finding the first element greater than or equal to X in the prefix sum of N numbers using Binary Lifting.

Prefix Sum of elements of an array is an array whose each element is the sum of all elements till that index in the initial array.

Example − array[] = {5, 2, 9, 4, 1}

prefixSumArray[] = {5, 7, 16, 20, 21}

Let's take an example to understand the problem,

Input: arr[] = {5, 2, 9, 4, 1}, X = 19
Output: 3

Solution Approach

Here, we will be solving the problem using the concept of binary lifting. Binary Lifting is increasing the value of the given number by powers of 2 (done by flipping bits) ranging from 0 to N.

We will be considering a concept similar to lifting binary trees where we will be finding the initial value of 'P' index. This is increased by flipping bits making sure the value is not greater than X. Now, we will be considering lift along with this position 'P'.

For this, we will start flipping bits of the number such that i-th bit flip does not make the sum greater than X. Now, we have two cases based on the value of 'P' −

Either the target position lies between 'position + 2^i' and 'position + 2^(i+1)' where the ith lift increased the value. Or, the target position lies between 'position' and 'position + 2^i'.

Using this we will be considering the index position.

Example

Program to illustrate the working of our solution

#include <iostream>
#include <math.h>
using namespace std;
void generatePrefixSum(int arr[], int prefSum[], int n){
   prefSum[0] = arr[0];
   for (int i = 1; i < n; i++)
      prefSum[i] = prefSum[i - 1] + arr[i];
}
int findPreSumIndexBL(int prefSum[], int n, int x){
   int P = 0;
   int LOGN = log2(n);
   if (x <= prefSum[0])
      return 0;
   for (int i = LOGN; i >= 0; i--) {
      if (P + (1 << i) < n &&
         prefSum[P + (1 << i)] < x) {
         P += (1 << i);
      }
   }
   return P + 1;
}
int main(){
   int arr[] = { 5, 2, 9, 4, 1 };
   int X = 19;
   int n = sizeof(arr) / sizeof(arr[0]);
   int prefSum[n] = { 0 };
   generatePrefixSum(arr, prefSum, n);
   cout<<"The index of first elements of the array greater than the given number is ";
   cout<<findPreSumIndexBL(prefSum, n, X);
   return 0;
}

Output

The index of first elements of the array greater than the given number is 3

Updated on: 01-Feb-2022

190 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements