📅  最后修改于: 2023-12-03 14:57:47.575000             🧑  作者: Mango
给定一个长度为n的非负整数序列,如何快速求出一个区间的所有数的和。
最简单的方法是对于每个查询操作,对区间内的所有数求和,时间复杂度为O(qn),其中q为查询的次数,n为序列长度。
由于查询操作涉及到连续的区间和,因此可以事先计算出所有前缀和,即sum[i]表示前i个数的和,然后对于每个查询操作,只需计算sum[r]-sum[l-1]即可得到区间[l,r]内数的和。时间复杂度为O(n+q)。
线段树是一种经典的数据结构,具有良好的时间复杂度和空间复杂度。可以用线段树来维护整个序列,对于每个节点维护其表示的区间和。查询操作时,对于区间[l,r],可以在O(log n)的时间内找到其在线段树上的对应节点,然后返回其区间和。时间复杂度为O(nlogn+qlogn)。
def prefix_sum(nums):
n = len(nums)
sum = [0] * n
sum[0] = nums[0]
for i in range(1,n):
sum[i] = sum[i-1] + nums[i]
return sum
def sum_between(sum,l,r):
if l == 0:
return sum[r]
else:
return sum[r] - sum[l-1]
class SegTree:
def __init__(self, nums):
self.n = len(nums)
self.tree = [0] * (4 * self.n)
self.build(nums, 1, 0, self.n-1)
def build(self, nums, i, l, r):
if l == r:
self.tree[i] = nums[l]
else:
m = (l + r) // 2
self.build(nums, 2*i, l, m)
self.build(nums, 2*i+1, m+1, r)
self.tree[i] = self.tree[2*i] + self.tree[2*i+1]
def query(self, i, ql, qr, l, r):
if ql <= l and qr >= r:
return self.tree[i]
elif ql > r or qr < l:
return 0
else:
m = (l + r) // 2
return self.query(2*i, ql, qr, l, m) + self.query(2*i+1, ql, qr, m+1, r)
以上代码仅是示例,具体实现细节还需根据不同情况进行调整。