看到uestc的資料結構專題快要結束了,感覺自己真心浪費了好多時間,沒有像鑫航學姐那樣叮囑的一樣,緊緊的跟住訓練。
所以下決心認認真真的開始學習下線段樹的知識,以前對於線段樹的學習都是一知半解的,就是說,我只知道線段樹是用來單點更新和區間查值的,其實,線段樹的功能遠遠不止這些。
先來說下,線段樹是用來求解有關區間問題的絕逼法寶,為什麼說絕逼呢。因為它能夠在logn的時間內完成每次的查詢。
查詢的分類:
1.區間查詢
-訪問某段區間的某些性質(比如說,最大值,最小值,連續和,等等)
2.區間更新
-某些操作影響了某段區間(比如說,統一加乙個值)
歸於以上兩個查詢,我們總結出了線段樹能夠解決的以下三個問題.
-更新點,查詢區間
-更新區間,查詢點
-更新區間,查詢區間
要想深入的理解線段樹,我們從乙個比較經典的例子開始了解吧。
我現在有乙個長度為 n的一維陣列(a[1]~a[n])
我們每次對這個陣列只允許有以下的操作:
~1.修改陣列中某個元素的值
- [1,5,4,1,6] ---(a[2] = 3)---[1,3,4,1,6]
~2.詢問陣列中某段區間的最大值
-[1,5,4,1,6] ---(max(1,4)=?) ---> 5
~3.詢問陣列中某段區間的和
-[1,5,4,1,6] ---(sum(3,5)=?) ---> 11
在沒有知道線段樹之前,我們知道,要對乙個陣列進行這樣的操作是很簡單的每次只要o(n)的時間掃一遍就是可以得到各種詢問的ans的。
那麼,如果我要進行q次詢問該怎麼辦呢?這樣的話就變成了o(nq)的複雜度了,,擦,,這也太慢了吧,隨便給你一組資料,你就t了
所以,為了在更快的時間裡解決這些查詢問題,我們引入了乙個叫做線段樹的資料結構,線段樹就是乙個能在logn的時間內完成每次操作。
線段樹的本質是一棵二叉樹,不同於一般的二叉樹來說,線段樹的每個節點維護的都是一段區間的資訊。
比如下面這個二叉樹,對於乙個長度為5的陣列a[1]~a[5]
[1,.5]
[1,3] [4,5]
[1,2] [3,3] [4,4] [5,5] 對於這個樹的構建有幾點說明,對於任意乙個非葉子節點來說,如果它所維護的區間是[l,r]的話,它的左兒子區
[1,1] [2,2] 間就是[l,(l+r)/2], 右兒子區間就是[(l+r)/2+1,r];
線段樹 ---實現
每個節點記錄的資訊
1struct
segtree
2tree[max*4];
我們先用乙個陣列a來記錄節點,並且根節點的下標為1,然後,對於任意乙個節點來說a[k]來說,他的左兒子是a[k<<1],右兒子是a[k<<1|1]
建立一棵線段樹**實現
void build ( int id,int l,intr )
else
}
線段樹學習
今天學習了線段樹。是敲了不少 可是感覺還沒有真正理解 先不貼題目。再消化消化。一會兒還有計組實驗。還有那個傲嬌的老師。真是煩。餓。先去吃飯去。一天木有吃。以下 線段樹模板 線段樹的節點 節點包括兩部分資訊,基本域,和資訊域 基本域 左右邊界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...