📜  数组中的范围总和和更新:使用堆栈的段树(1)

📅  最后修改于: 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)
使用堆栈的段树的优点

使用堆栈的方式,使代码实现更加简洁,可维护性更高。

总结

使用堆栈的段树可以方便地处理数组范围求和和修改问题,提高代码的效率和可维护性。