给定一个由N个整数和一个数字X组成的数组。任务是在N个数字的前缀总和中找到大于或等于X的第一个元素的索引。
例子:
Input: arr[] = { 2, 5, 7, 1, 6, 9, 12, 4, 6 } and x = 8
Output: 2
prefix sum array formed is { 2, 7, 14, 15, 21, 30, 42, 46, 52}, hence 14 is the number whose index is 2
Input: arr[] = { 2, 5, 7, 1, 6, 9, 12, 4, 6 } and x = 30
Output: 5
方法:可以在二进制搜索中使用lower_bound函数解决该问题。但是在本文中,将使用Binary-Lifting解决该问题。在二进制提升中,值以2的幂增加(或提升),从可能的最高2(log(N))降到最低功率(0)。
- 初始化position = 0并设置位置的每个位,从最高有效位到最低有效位。
- 只要将位设置为1,位置值就会增加(或升高)。
- 在增加或提升位置时,请确保前缀和直到位置应小于v。
- 在这里,“位置”的所有可能值(从log(N)到第0位)都需要log(N)位。
- 确定第i位的值。首先,检查设置第i位是否不会使“位置”大于N(即数组的大小)。在提升到新的“位置”之前,请检查该新“位置”处的值是否小于X。
- 如果此条件为真,则目标位置位于“位置” + 2 ^ i之上,但低于“位置” + 2 ^(i + 1)。这是因为如果目标位置在“ position” + 2 ^(i + 1)之上,则该位置将已经被提升2 ^(i + 1) (此逻辑类似于树中的二进制提升)。
- 如果为假,则目标值位于‘position’和’position’+ 2 ^ i之间,因此尝试提升2的较低乘方。最后,循环将结束,以使该位置的值小于X。在这个问题中,要求下限。因此,返回‘position’+ 1 。
下面是上述方法的实现:
C++
// CPP program to find lower_bound of x in
// prefix sums array using binary lifting.
#include
using namespace std;
// function to make prefix sums array
void MakePreSum(int arr[], int presum[], int n)
{
presum[0] = arr[0];
for (int i = 1; i < n; i++)
presum[i] = presum[i - 1] + arr[i];
}
// function to find lower_bound of x in
// prefix sums array using binary lifting.
int BinaryLifting(int presum[], int n, int x)
{
// intisalize position
int pos = 0;
// find log to the base 2 value of n.
int LOGN = log2(n);
// if x less than first number.
if (x <= presum[0])
return 0;
// starting from most significant bit.
for (int i = LOGN; i >= 0; i--) {
// if value at this position less
// than x then updateposition
// Here (1<
Java
// Java program to find lower_bound of x in
// prefix sums array using binary lifting.
import java.util.*;
class solution
{
// function to make prefix sums array
static void MakePreSum(int []arr, int []presum, int n)
{
presum[0] = arr[0];
for (int i = 1; i < n; i++)
presum[i] = presum[i - 1] + arr[i];
}
// function to find lower_bound of x in
// prefix sums array using binary lifting.
static int BinaryLifting(int []presum, int n, int x)
{
// intisalize position
int pos = 0;
// find log to the base 2 value of n.
int LOGN = (int)Math.log(n);
// if x less than first number.
if (x <= presum[0])
return 0;
// starting from most significant bit.
for (int i = LOGN; i >= 0; i--) {
// if value at this position less
// than x then updateposition
// Here (1<
Python 3
# Python 3 program to find
# lower_bound of x in prefix
# sums array using binary lifting.
import math
# function to make prefix
# sums array
def MakePreSum( arr, presum, n):
presum[0] = arr[0]
for i in range(1, n):
presum[i] = presum[i - 1] + arr[i]
# function to find lower_bound of x in
# prefix sums array using binary lifting.
def BinaryLifting(presum, n, x):
# intisalize position
pos = 0
# find log to the base 2
# value of n.
LOGN = int(math.log2(n))
# if x less than first number.
if (x <= presum[0]):
return 0
# starting from most significant bit.
for i in range(LOGN, -1, -1) :
# if value at this position less
# than x then updateposition
# Here (1<
C#
// C# program to find lower_bound of x in
// prefix sums array using binary lifting.
using System;
class GFG
{
// function to make prefix sums array
static void MakePreSum(int []arr,
int []presum, int n)
{
presum[0] = arr[0];
for (int i = 1; i < n; i++)
presum[i] = presum[i - 1] + arr[i];
}
// function to find lower_bound of x in
// prefix sums array using binary lifting.
static int BinaryLifting(int []presum,
int n, int x)
{
// intisalize position
int pos = 0;
// find log to the base 2 value of n.
int LOGN = (int)Math.Log(n);
// if x less than first number.
if (x <= presum[0])
return 0;
// starting from most significant bit.
for (int i = LOGN; i >= 0; i--)
{
// if value at this position less
// than x then updateposition
// Here (1<
输出:
2
时间复杂度: O(N)
辅助空间: O(N)