線段樹的學習記錄

2021-06-26 09:11:36 字數 1413 閱讀 9109

線段樹的學習記錄

1、區間查詢:詢問某段區間的某些性質(極值、求和、

etc)

2、區間更新:某些操作影響了某些區間(統一加乙個值)

3、三個問題: 更新點,查詢區間

更新區間,查詢點

更新區間,查詢區間

例如:乙個長度為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)

更多的詢問?

q次詢問,

o(nq)  

that's too slow!

線段樹——在o(log2n)

的時間內完成每次操作 

o(qlog2n)

less than 1 second when n=q=100000

線段樹的本質是一棵二叉樹,不同於其它二叉樹,線段樹的每乙個節點記錄的是一段區間的資訊。

對於任一非葉子節點,若該區間為[l,r],則

左兒子為[l,(l+r)/2]

右兒子為[(l+r)/2+1,r]

每乙個節點記錄的資訊?

struct tree

;線段樹——**實現(建樹)

void build(int id,int l,int r)

else

}

如果原陣列從a[1]~a[n],呼叫build(1,1,n)即可。

線段樹——**實現(更新)

更新某個點的數值,並維護相關點的資訊

void update(int id,int pos,int val)

else

}

若更新a[k]的值為val,呼叫update(1,k,val)即可。

查詢某區間內元素的和或最大值(以總和為例)

void query(int id,int l,int r)

}

呼叫query(1,l,r)即可查詢[l,r]區間內元素的總和。

線段樹——空間複雜度

更新操作:由於總是一條路徑從根到某個葉子,而樹的深度為log2n,因而為o(log2n)

查詢操作:每層被訪問的節點不超過4個,因而同樣為o(log2n)

線段樹——空間複雜度

線段樹學習

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