线段树(Segment Tree)

一句话说明

线段树就是把区间不断二分,每个节点只负责一段区间的答案。

Go 代码:区间和

type SegmentTree struct {
    n    int
    tree []int
}
 
func NewSegmentTree(nums []int) *SegmentTree {
    st := &SegmentTree{n: len(nums), tree: make([]int, 4*len(nums))}
    if len(nums) > 0 {
        st.build(1, 0, len(nums)-1, nums)
    }
    return st
}
 
func (st *SegmentTree) build(node, left, right int, nums []int) {
    if left == right {
        st.tree[node] = nums[left]
        return
    }
    mid := left + (right-left)/2
    st.build(node*2, left, mid, nums)
    st.build(node*2+1, mid+1, right, nums)
    st.tree[node] = st.tree[node*2] + st.tree[node*2+1]
}
 
func (st *SegmentTree) Query(l, r int) int {
    var query func(node, left, right int) int
    query = func(node, left, right int) int {
        if l <= left && right <= r {
            return st.tree[node]
        }
        mid := left + (right-left)/2
        ans := 0
        if l <= mid {
            ans += query(node*2, left, mid)
        }
        if r > mid {
            ans += query(node*2+1, mid+1, right)
        }
        return ans
    }
    return query(1, 0, st.n-1)
}

关键点

节点维护什么信息,决定了线段树能解决什么问题。区间和、最大值、最小值、懒标记,都是同一套骨架。

相关主题


返回:树算法 | 算法学习导航