1. 程式人生 > >線段樹與樹狀數組的綜合運用

線段樹與樹狀數組的綜合運用

兩個 遇到 省選 情況 莫隊 erl lib 答案 rmq

前言:線段樹樹狀數組是高級數據結構最基本的部分,數據結構又是省選最基本的部分,所以從他開始整理一下。

題目以洛谷和bz為基底

1.基礎運用

數據結構最基本的問題就是操作和詢問的問題,

修改可以分為點修改(包括點的函數運算) 區間運算 區間最大最小和取模 區間set

其中點修改就是領出樹上的一條長鏈,對其末端進行花式操作

區間修改就有點意思了

{

寫過線段樹再過來看寒文的人大概都爛熟lazy tag 這個東西剛學的時候確實還是一個障礙。

劉汝佳的藍書上提到了區間set 這其實並不難只是難寫吧(區間maxmin和區間set一樣 下傳標記加個if就可以)

區間取模我還是在一個PDF裏學的 其精髓是保存節點附加信息的時候多三個——

maxsumofmaxsecondmax(看名字能理解吧)然後

我們來試著打一打補丁。

下面為引用

? 對線段樹上的每一個區間維護區間最大值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.有待發現

學習無止境~~~~~~~~~

線段樹與樹狀數組的綜合運用