📌  相关文章
📜  Q查询的所有小于X且大于Y的数组元素的总和

📅  最后修改于: 2021-05-19 19:25:06             🧑  作者: Mango

给定一个已排序的数组arr []和一个具有M个查询的集合Q ,其中每个查询具有值XY ,任务是查找数组中存在的所有小于X且大于Y的整数的总和。
注意: X和Y可能会或可能不会出现在数组中。

例子:

方法:

  1. 构建一个前缀和数组,其中prefix_sum [i]表示arr [0] + arr [1] +…arr [i]的和
  2. 找到值小于X的最后一个索引i ,然后提取前缀总和直到第i索引。通过分别在Python和C++中使用bisect_left()或lower_bound(),可以以O(logN)复杂度获得索引。
  3. 同样,在数组中找到第一个索引i ,其值大于Y,然后计算出总和prefix_sum [n-1] – prefix_sum [i-1] 。分别在Python和C++中的内置函数bisect()和upper_bound()在O(logN)中执行所需的操作。
  4. 在以上两个步骤中计算出的两个结果的总和是必需的答案。继续对每个查询重复这些步骤。

下面是上述方法的实现:

Python3
# Python code for the above program
from bisect import bisect, bisect_left
  
def createPrefixSum(ar, n):
  
    # Initialize prefix sum 
    # array
    prefix_sum = [0]*n
  
    # Initialize prefix_sum[0]
    # by ar[0]
    prefix_sum[0] = ar[0]
      
    # Compute prefix sum for
    # all indices    
    for i in range(1, n):
        prefix_sum[i] = prefix_sum[i-1]+ar[i]
    return prefix_sum
  
# Function to return sum of all
# elements less than X
def sumLessThanX(ar, x, prefix_xum):
  
    # Index of the last element 
    # which is less than x
    pos_x = bisect_left(ar, x) - 1
  
      
    if pos_x >= 0 :
        return prefix_sum[pos_x]
    # If no element is less than x
    else:
        return 0
  
# Function to return sum of all
# elements greater than Y
def sumGreaterThanY(ar, y, prefix_sum):
  
    # Index of the first element 
    # which is greater than y
    pos_y = bisect(ar, y)
    pos_y -= 1
  
    if pos_y < len(ar)-1 :
        return prefix_sum[-1]-prefix_sum[pos_y]
    # If no element is greater than y
    else:
        return 0
  
  
def solve(ar, x, y, prefix_sum):
    ltx = sumLessThanX(ar, x, prefix_sum)
    gty = sumGreaterThanY(ar, y, prefix_sum)
  
    # printing the final sum
    print(ltx + gty) 
  
  
def print_l(lb, ub):
    print("sum of integers less than {}".format(lb)
    + " and greater than {} is ".format(ub),
    end = '')
  
  
if __name__ == '__main__':
  
    # example 1
    ar = [3, 6, 6, 12, 15]
    n = len(ar)
    prefix_sum = createPrefixSum(ar, n)
  
    # for query 1
    q1x = 5
    q1y = 12
    print_l(q1x, q1y)
    solve(ar, q1x, q1y, prefix_sum)
  
    # for query 2
    q2x = 7
    q2y = 8
    print_l(q2x, q2y)
    solve(ar, q2x, q2y, prefix_sum)


输出:
sum of integers less than 5 and greater than 12 is 18
sum of integers less than 7 and greater than 8 is 42


时间复杂度: O(N +(M * logN))
辅助空间复杂度: O(N)