線段樹與樹狀數組的綜合運用
前言:線段樹樹狀數組是高級數據結構最基本的部分,數據結構又是省選最基本的部分,所以從他開始整理一下。
題目以洛谷和bz為基底
1.基礎運用
數據結構最基本的問題就是操作和詢問的問題,
修改可以分為點修改(包括點的函數運算) 區間運算 區間最大最小和取模 區間set
其中點修改就是領出樹上的一條長鏈,對其末端進行花式操作
區間修改就有點意思了
{
寫過線段樹再過來看寒文的人大概都爛熟lazy tag 這個東西剛學的時候確實還是一個障礙。
劉汝佳的藍書上提到了區間set 這其實並不難只是難寫吧(區間maxmin和區間set一樣 下傳標記加個if就可以)
區間取模我還是在一個PDF裏學的 其精髓是保存節點附加信息的時候多三個——
我們來試著打一打補丁。
下面為引用
? 對線段樹上的每一個區間維護區間最大值mx,這個區間中最大值出 現的次數t,區間次大值se,當然還要維護區間和sum ? 現在考慮打上區間取min標記x:
? 如果mx<=x,那麽對sum就沒有修改。
? 如果se<x<mx,那麽sum=sum-(mx-x)×t。
? 如果x<=se<mx,那麽…
? 如果遇到這種情況,我們分別DFS這個節點的兩個孩子,如果當前 DFS的過程中遇到了前兩種情況,就直接修改打上標記然後退出,否 則就繼續DFS。
}
查詢則有點查詢(因為毫無意義實在不常見)區間和查詢
由於點修改點查詢是數組的運用。。。。於是就從區間查詢開始
·區間和查詢
這是最基本的一種線段樹(樹狀數組運用)建議一個月寫一下保持手感
洛谷p3374就很好不過線段樹只能打70,無視就好
另外p3372線段樹模板1P2023 [AHOI2009]維護序列都不錯
·區間運算。這個其實還分很多種,不過都是在節點信息上做手腳(註意lazytag運用結合律的姿勢)
P3373線段樹模板2
·區間最大最小值
RMQRMQRMQMRMQ問題。。。。。。請線段樹只是處理動態問題的rmq,極為好寫因為這其實是點查詢。。。。。。
P3865ST表(線段樹還是70,無視即可)
·歷史查詢最大值。
我們把修改映射到樹上。
比如12345的樹我們觀察到查詢的節點(記錄下來)發生了+a,+b,=0,=c,-d,+e……的操作,求得就是這個東西的區間最大。
如果有乘除模和函數運算,就不大好弄了(有待更新)
這其實是一個小應用,它包含的是下面的思想但是我們觀察到樹高度達不到1000,
所以m(query times)log^2 n的動規解決也可以,這個復雜度雖然容易被卡但是n1000000,m1000000的數據還是很大概率可以的,動規加點卡常也許就很穩了。
·動態數列區間最大子段和
藍書上的例題9 LA3938援引洛杉磯大學題庫裏的。
線段樹,建樹過程中要標記
max_all:最大連續和
max_prefix:最大前綴和
max_suffix:最大後綴和
pre_r:最大前綴的結束位置
suf_l:最大後綴的開始位置
sum:區間總和
對於更新,由於要x盡量小與y盡量小,所以在更新的時候我們要確定好更新的順序,也就是l先盡量小,然後才是y盡量小
更新有5種狀況,那麽按順序就是
1.左邊的sum+右區間的max_prefix;
2.左區間max_all
3.左邊的max_suffix+右邊的max_prefix
4.左邊的max_suffix+右邊的sum
5.右邊的max_all
可以說是很有首創難度思維難度。
題目:有待更新
2.改變存點方式。
印象最深的改變點的信息就是主席樹了。。。。
La4329不錯
這個東西其實是一類大型題目(考爛了)
分塊莫隊都可以解決
P2184貪婪大陸
P1972HH的項鏈
P1908逆序對
這類題目都可以用桶子數組前綴和的方式解決
什麽意思呢,就是離散化保存set,加入就改它的對應位置+1,這個時候解決的就是區間個數差問題(前綴和思想)
3.有待發現
學習無止境~~~~~~~~~
線段樹與樹狀數組的綜合運用