學習線段樹

2021-09-30 03:57:11 字數 1333 閱讀 9961

參考文章:

從簡單說起,線段樹其實可以理解成一種特殊的二叉樹。但是這種二叉樹較為平衡,和靜態二叉樹一樣,都是提前已經建立好的樹形結構。針對性強,所以效率要高。這裡又想到了一句題外話:動態和靜態的差別。動態結構較為靈活,但是速度較慢;靜態結構沒有節省記憶體,但速度較快。演算法導論中有涉及區間樹的內容,那裡用紅黑樹來進行維護。本文主要講靜態的線段樹。

長度範圍為[1 , l] 的一棵線段樹的深度為log ( l - 1 ) + 1。這個顯然,而且儲存一棵線段樹的空間複雜度為o(l)。

線段樹支援最基本的操作為插入和刪除一條線段。下面已插入為例,詳細敘述,刪除類似。

將一條線段[a , b] 插入到代表線段[l , r]的結點p中,如果p不是元線段,那麼令mid=(l+r)/2。如果amid,那麼將線段[a , b] 也插入到p的右兒子結點中。

插入(刪除)操作的時間複雜度為o ( log n )。

線段樹其最簡單的應用就是記錄線段有否被覆蓋,並隨時查詢當前被覆蓋線段的總長度。那麼此時可以在結點結構中加入乙個變數int coverlength;代表當前結點代表的子樹中被覆蓋的線段長度和。這樣就要在插入(刪除)當中維護這個coverlength值,於是當前的覆蓋總值就是根節點的coverlength值了。

另外也可以將coverlength換成bool cover;支援查詢乙個結點或線段是否被覆蓋。

根據上面的討論,我們設計線段樹的節點結構為

count:線段覆蓋條數,當插入線段完全覆蓋線段樹上的區間時( left<=node.left && node.right<=right ),count才增長,否則,就將該線段插入到子節點中。

covlen:測度,通俗點說,就是該區間中被覆蓋過線段的總長度。當該區間的count>1時,covlen等於該區間的長度,如果是離散化之後的線段樹,就加上對應的線段的長度。如果這個節點不是內部節點而是葉節點並且count=0,那covlen就等於0。如果這個節點的count等於0,但是他是內部節點,那麼covlen就等於他左右子節點的covlen值的和。

numoflines連續段數:就是該區間上連續線段的條數,比如線段樹[1,10]上,有兩條線段[1,5],[8,10],那麼[1,10]這個區間上的連續線段的條數就是2;如果有兩條線段是[1,5],[5,10],那麼該區間上連續線段條數就是1。由此可以看出,連續線段條數,與該節點的左右子節點上的左右端點的覆蓋情況有關,因此還有設立2個域lbd, rbd表示該區間的左右端點的覆蓋情況。

---------------------------完整線段樹**------------------------------------------

理解**後,可以到poj 2777 count color 和 poj 3264 balanced lineup去小試身手。

線段樹學習

今天學習了線段樹。是敲了不少 可是感覺還沒有真正理解 先不貼題目。再消化消化。一會兒還有計組實驗。還有那個傲嬌的老師。真是煩。餓。先去吃飯去。一天木有吃。以下 線段樹模板 線段樹的節點 節點包括兩部分資訊,基本域,和資訊域 基本域 左右邊界ld,rd.左右孩子 lc,rc 資訊域 key值,如rmq...

留待學習線段樹

include define lson l m rt 1 define rson m 1 r rt 1 1 const int maxn 55555 int sum maxn 2 void pushup int rt void build int l,int r,int rt int m l r 1...

線段樹學習筆記

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