線段樹的學習記錄
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...