第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

線段樹入門詳解:從基礎(chǔ)到應(yīng)用

概述

线段树是一种高效的数据结构,特别适用于处理静态或动态数组的区间查询和更新操作。它能够在较短的时间内完成对数组内某些区间的查询和更新操作。线段树的基本思想是将原数组划分成多个区间,并为每个区间创建一个节点,以树状结构表示。线段树的应用场景非常广泛,包括区间最大值/最小值查询、区间和查询、区间更新等。

线段树简介

线段树是一种高效的数据结构,特别适用于处理静态或动态数组的区间查询和更新操作。它能够在较短的时间内完成对数组内某些区间的查询和更新操作。线段树的基本思想是将原数组划分成多个区间,并为每个区间创建一个节点,以树状结构表示。每个节点代表一个区间,而每个叶子节点代表原数组中的一个元素。

线段树的应用场景

常见的应用场景包括:

  1. 区间最大值/最小值查询:给定一个数组,查询某个区间内的最大值或最小值。
  2. 区间和查询:给定一个数组,查询某个区间内的元素之和。
  3. 区间更新:给定一个数组,更新某个区间内所有元素的值。
  4. 区间排序:利用线段树进行区间内元素的排序操作。
  5. 前缀和后缀查询:查询数组的前缀或后缀和。
线段树的构建方法

线段树的节点结构

一个线段树节点通常包含以下几个属性:

  1. start:该节点表示的区间的起点。
  2. end:该节点表示的区间的终点。
  3. sum:该节点表示的区间的和。
  4. left:该节点的左子节点。
  5. right:该节点的右子节点。
class Node:
    def __init__(self, start, end):
        self.start = start
        self.end = end
        self.sum = 0
        self.left = None
        self.right = None

线段树的递归构建过程

线段树的构建过程可以使用递归实现。首先创建一个根节点,该节点表示整个数组的区间。接下来,递归地创建左右子节点,每个子节点表示原区间的一半。当区间长度为1时,递归过程结束。

def build_tree(start, end):
    node = Node(start, end)
    if start == end:
        return node
    mid = (start + end) // 2
    node.left = build_tree(start, mid)
    node.right = build_tree(mid + 1, end)
    return node
线段树的基本操作

查询操作详解

在查询操作中,我们通常需要计算某个区间内的元素之和。当查询的区间完全包含节点表示的区间时,可以使用节点的sum属性。当查询的区间完全不包含节点表示的区间时,结果为0。否则,递归地向左右子节点查询。

def query(node, q_left, q_right):
    if q_left <= node.start and node.end <= q_right:
        return node.sum
    if q_right < node.start or node.end < q_left:
        return 0
    return query(node.left, q_left, q_right) + query(node.right, q_left, q_right)

更新操作详解

在更新操作中,我们通常需要更新某个区间内所有元素的值。当更新的区间完全包含节点表示的区间时,直接更新节点的sum属性。当更新的区间完全不包含节点表示的区间时,不需要进行任何操作。否则,递归地向左右子节点更新。

def update(node, index, value):
    if node.start == node.end:
        node.sum = value
        return
    mid = (node.start + node.end) // 2
    if index <= mid:
        update(node.left, index, value)
    else:
        update(node.right, index, value)
    node.sum = node.left.sum + node.right.sum
线段树的优化技巧

线段树的延迟更新

在某些情况下,我们可以将更新操作延迟到真正需要使用时进行,以提高更新效率。具体来说,当需要更新某个区间时,如果该区间完全包含于某个节点表示的区间,我们可以将更新操作向下传递,并标记该节点为“待更新”。当真正需要使用节点的sum属性时,再进行更新操作。

class LazyNode:
    def __init__(self, start, end):
        self.start = start
        self.end = end
        self.sum = 0
        self.lazy = 0
        self.left = None
        self.right = None

def push_down(node):
    mid = (node.start + node.end) // 2
    if node.left is None:
        node.left = LazyNode(node.start, mid)
    if node.right is None:
        node.right = LazyNode(mid + 1, node.end)
    if node.lazy:
        node.left.sum += node.lazy * (mid - node.start + 1)
        node.right.sum += node.lazy * (node.end - mid)
        node.left.lazy += node.lazy
        node.right.lazy += node.lazy
        node.lazy = 0

def update(node, q_left, q_right, value):
    if q_left <= node.start and node.end <= q_right:
        node.sum += value * (node.end - node.start + 1)
        node.lazy += value
        return
    push_down(node)
    mid = (node.start + node.end) // 2
    if q_left <= mid:
        update(node.left, q_left, q_right, value)
    if q_right > mid:
        update(node.right, q_left, q_right, value)
    node.sum = node.left.sum + node.right.sum

def query(node, q_left, q_right):
    if q_left <= node.start and node.end <= q_right:
        return node.sum
    push_down(node)
    mid = (node.start + node.end) // 2
    res = 0
    if q_left <= mid:
        res += query(node.left, q_left, q_right)
    if q_right > mid:
        res += query(node.right, q_left, q_right)
    return res

线段树的区间合并

在线段树中,我们可以通过合并左右子节点的结果来计算整个区间的属性。这种方法可以避免重复计算,提高查询和更新效率。

class Node:
    def __init__(self, start, end):
        self.start = start
        self.end = end
        self.children = []

def merge(node):
    if node is None or len(node.children) == 0:
        return
    node.sum = sum([child.sum for child in node.children])
    for child in node.children:
        merge(child)
线段树实例分析

实际问题的线段树解决方法

举个简单的例子,假设我们有一个长度为n的数组,需要频繁地对数组中的某个区间进行查询或更新操作。我们可以使用线段树来实现高效的操作。具体的解决方案如下:

  1. 构建线段树,将数组的每个元素作为叶子节点。
  2. 对于每个区间查询操作,使用查询操作计算该区间内的元素之和。
  3. 对于每个区间更新操作,递归地更新每个区间内所有元素的值。

线段树代码实现示例

下面是线段树的完整代码实现。这段代码实现了线段树的构建、查询和更新操作。

class Node:
    def __init__(self, start, end):
        self.start = start
        self.end = end
        self.sum = 0
        self.left = None
        self.right = None

def build_tree(start, end):
    node = Node(start, end)
    if start == end:
        return node
    mid = (start + end) // 2
    node.left = build_tree(start, mid)
    node.right = build_tree(mid + 1, end)
    return node

def query(node, q_left, q_right):
    if q_left <= node.start and node.end <= q_right:
        return node.sum
    if q_right < node.start or node.end < q_left:
        return 0
    return query(node.left, q_left, q_right) + query(node.right, q_left, q_right)

def update(node, index, value):
    if node.start == node.end:
        node.sum = value
        return
    mid = (node.start + node.end) // 2
    if index <= mid:
        update(node.left, index, value)
    else:
        update(node.right, index, value)
    node.sum = node.left.sum + node.right.sum

# 示例
n = 10
arr = [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
tree = build_tree(0, n - 1)

for i in range(n):
    update(tree, i, arr[i])

print(query(tree, 2, 5))  # 输出 21
update(tree, 5, 11)
print(query(tree, 2, 5))  # 输出 26
线段树练习题推荐

入门级练习题

  1. 给定一个长度为n的数组,实现区间查询和更新操作。
  2. 实现一个区间最大值查询功能。
  3. 实现一个区间最小值查询功能。

进阶级练习题

  1. 实现一个区间排序功能。
  2. 实现一个前缀和后缀查询功能。
  3. 对线段树进行优化,实现延迟更新和区间合并功能。
點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評(píng)論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會(huì)直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消