筆記 線段樹

2021-08-16 08:01:43 字數 1305 閱讀 2334

一顆二叉樹,即為t(a,b),引數a,b表示該節點表示區間[a,b]。區間長度b-a記為l。遞迴定義t[a,b]:

若區間長度l>1:區間[a

,⌊a+

b2⌋]

[ a,

⌊a+b

2⌋]為t的左兒子,區間[⌊

a+b2

⌋+1,

b][ ⌊a

+b2⌋

+1,b

]為t的右兒子。

若區間長度l=1:t為乙個葉子結點,表示區間[a]。

葉結點為區間內的所有資料點。在對分枝結點的區間中點分界時,資料點要麼落在左子樹的底層,要麼落在右子樹的底層。如果進行區間運算的話,則可能存在「跨越」的情況,刪除或插入區間內的每個點時都必須深入到葉結點,因此一般來說需要lo

g2n log

2n的時間複雜度。線段樹一方面可以方便計數,另一方面由於它實際上是排序二叉樹,所以容易找出最大值和最小值來。

線段樹一般採用結構陣列a儲存,如果結點a[i]代表區間[l,r]的話,則左兒子a[2*i]代表左子區間[l

,⌊l+

r2⌋]

[ l,

⌊l+r

2⌋],右兒子a[2*i+1]代表右子區間[⌊

l+r2

⌋+1,

r][ ⌊l

+r2⌋

+1,r

]。每個節點除需要記錄所代表區間的左右指標外,還可根據需要增設一些特殊的資料域,例如所代表的子區間是否為空;如果不為空的話,有多少線段覆蓋本子區間,或哪些資料落在本子區間內,以便插入或刪除線段時動態維護。

線段樹的基本操作包括:

在區間[l,r]插入或刪除線段操作前,需要為該區間建立一顆線段樹,依照二分策略將區間[l,r]劃分出to

t(to

t≤2∗

log2

(r−l

))t ot

(tot

≤2∗l

og2(

r−l)

)個空的子區間,這些子區間暫且未被任何線段所覆蓋。tot為全域性變數,記錄一共用到了多少個節點。建樹前tot=0,建立線段樹t(l,r)的過程:

void build_tree(int l,int r,int i)

在插入、刪除線段或資料操作前,一般需要呼叫build過程,設定結點序號、左右指標和資料域初始化。

筆記 線段樹

線段樹和樹狀陣列的功能類似 但是比樹狀陣列強大的是 線段樹可以進行區間的更新操作 不只是單點更新 如把陣列1 3加5 或者把陣列5 6全部改為4 等等 但是線段樹的 量比樹狀陣列要大 記住線段樹的記憶體是普通的四倍!下面 線段樹輸入乙個陣列 改變區間l到r 使a陣列l到r每個加上d 求區間ll到rr...

線段樹學習筆記

線段樹是一種 二叉搜尋樹 與區間樹 相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。使用線段樹可以快速的查詢某乙個節點在若干條線段中出現的次數,時間複雜度為o logn 而未優化的 空間複雜度 為2n,因此有時需要離散化讓空間壓縮。以下筆記摘自lcomyn神犇部落格 1....

線段樹學習筆記

本文筆記在參考一步一步理解線段樹 tenos的基礎上形成 線段樹,也是二叉搜尋樹的一種,是基於陣列,但是優於陣列的一種資料結構。同時結合預處理 時間複雜度一般在o n 使得從原來陣列的o n 的查詢和更新複雜度降到了o logn 在處理很大資料量的資料更新和查詢最值方面變得簡單,值得一提的是,它的構...