成段更新的重點是延遲更新,以區間[1,3]為例說明。
注意,此例中「更新」為修改元素的值為a,「查詢」為求區間中所有元素之和。
建立二叉樹如圖示:
每乙個圓圈代表乙個結點,圓內數字分別為結點標號和所對應區間,[i]表示只含乙個數,只出現在葉節點中。
當 要更新區間[1,2]中所有元素時,對應上圖即要更新結點4,5。一種方法是依次訪問結點4和5並更新,但這樣時間和空間開銷都較大,當要修改的區間的長 度較長時尤甚。於是可以採取「延遲更新」,即將更新資訊儲存在這段區間對應的結點處,此例中 [1,2]對應的區間是結點2,給結點乙個屬性tag用以 記錄這個更新資訊a,原來tag初始化為0,此時令tag = a。這樣做實際上是將整乙個區間[1,2]看做乙個「點」,即應用單點更新。這樣做的好處 是不需要更新結點4和5。而事實上,在這一步中我們也只需要知道整乙個區間[1,2]的情況就足矣,如果以後每次查詢都是查詢整乙個區間[1,2],又何 須分別更新結點1和2?但是,存在一些情況,如查詢區間[2,3],由於上一次我們只更新了整乙個區間[1,2]所對應的結點2,而沒有更新結點2,此時 查詢[2,3]會導致錯誤。此時tag起作用。要查詢到結點5必須經過結點2,經過每乙個結點均檢查標識tag,若tag非0,表明上次沒有往下執行更 新,於是執行往下更新的操作:更新1和2,然後對結點2的tag置0。
延遲更新的方法就是:當前父結點儲存更新資訊而不往下更新以減少時間可空間開銷,當下次用到時再區域性更新。
線段樹(單點更新and成段更新)
線段樹需要的空間。區間為1 n 假設是一棵完全二叉樹,且樹高為i。完全二叉樹性質 第i層最多有2 i 1 個結點。那麼 2 i 1 n i log2 n 1 共有 2 i 1 個結點,即 2 log2 n 1 1個結點 即2 2 log2 n 1 2 n 1 但這是建立樹是完全二叉樹的情況下。但是如...
線段樹成段更新 MB
include include using namespace std struct node a 4 1100000 int dp 1100000 n,m long long max long long int x,long long int y void build int l,int r,in...
Just a Hook(線段樹,成段更新)
題目傳送門 just a hook t組資料 每組有乙個長度為n的序列,給你m次操作,每次操作給你x,y,z三個數,操作 將x到y的數字變為z m次操作完成後求序列的總和 很明顯的線段樹題目,維護區間和即可 注意一下更新區間的方法即可 對於修改不能直接更新到底部,要成段更新 include usin...