📅  最后修改于: 2023-12-03 15:10:22.061000             🧑  作者: Mango
在程序开发中,我们经常需要对数组中的一部分进行求和或修改,这就需要使用到数据结构中的段树。本文将介绍如何使用堆栈的方式实现带有范围求和和修改的段树。
堆栈(stack),有时也称为栈或堆叠,是一种后进先出(LIFO,last in first out)的抽象数据类型,用作运算元素的存储结构。栈是限定仅在表尾进行插入和删除操作的线性表。
段树是一种二叉树数据结构,一般用于处理区间问题。它将一个区间划分成多个小区间,每个小区间对应一个叶子节点,并在非叶子节点上记录对应区间的信息,如区间和、最大值、最小值等。段树最重要的性质是:每个节点的区间是其子节点区间的并集。
使用堆栈可以使代码更加简洁,代码实现如下:
class SegmentTree:
def __init__(self, nums):
self.n = len(nums)
self.tree = [0] * (self.n * 4)
self.lazy = [0] * (self.n * 4)
self.buildTree(nums, 0, 0, self.n-1)
def pushUp(self, node):
self.tree[node] = self.tree[node*2+1] + self.tree[node*2+2]
def pushDown(self, node, start, end):
if self.lazy[node] != 0:
self.tree[node] += (end-start+1) * self.lazy[node]
if start != end:
self.lazy[node*2+1] += self.lazy[node]
self.lazy[node*2+2] += self.lazy[node]
self.lazy[node] = 0
def buildTree(self, nums, node, start, end):
if start == end:
self.tree[node] = nums[start]
else:
mid = (start + end) // 2
self.buildTree(nums, node*2+1, start, mid)
self.buildTree(nums, node*2+2, mid+1, end)
self.pushUp(node)
def update(self, i, j, val):
self.updateTree(i, j, val, 0, 0, self.n-1)
def updateTree(self, i, j, val, node, start, end):
self.pushDown(node, start, end)
if j < start or i > end:
return
if i <= start and j >= end:
self.tree[node] += (end-start+1) * val
if start != end:
self.lazy[node*2+1] += val
self.lazy[node*2+2] += val
return
mid = (start + end) // 2
self.updateTree(i, j, val, node*2+1, start, mid)
self.updateTree(i, j, val, node*2+2, mid+1, end)
self.pushUp(node)
def query(self, i, j):
return self.queryTree(i, j, 0, 0, self.n-1)
def queryTree(self, i, j, node, start, end):
self.pushDown(node, start, end)
if j < start or i > end:
return 0
if i <= start and j >= end:
return self.tree[node]
mid = (start + end) // 2
return self.queryTree(i, j, node*2+1, start, mid) + self.queryTree(i, j, node*2+2, mid+1, end)
使用堆栈的方式,使代码实现更加简洁,可维护性更高。
使用堆栈的段树可以方便地处理数组范围求和和修改问题,提高代码的效率和可维护性。