📌  相关文章
📜  使用Binary Lifting在N个数字的前缀和中大于或等于X的第一个元素

📅  最后修改于: 2021-05-04 22:01:54             🧑  作者: Mango

给定一个由N个整数和一个数字X组成的数组。任务是在N个数字的前缀总和中找到大于或等于X的第一个元素的索引。

例子:

方法:可以在二进制搜索中使用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)