lazy-tag思想,記錄每乙個線段樹節點的變化值,當這部分線段的一致性被破壞我們就將這個變化值傳遞給子區間,大大增加了線段樹的效率。
在此通俗的解釋我理解的lazy意思:
現在需要對[a,b]區間值進行加c操作,那麼就從根節點[1,n]開始呼叫update函式進行更新操作;如果剛好執行到乙個rt節點,而且tree[rt].l == a && tree[rt].r == b,這時我們就應該一步更新此時rt節點的sum[rt]的值(sum[rt]+=c* (tree[rt].r - tree[rt].l + 1))。
關鍵來了,如果此時按照常規的線段樹的update操作,這時候還應該更新rt子節點的sum值,而lazy思想恰恰是暫時不更新rt子節點的sum值,而是在這裡打乙個tag,直接return。直到下次需要用到rt子節點的值的時候才去更新,這樣避免許多可能無用的操作,從而節省時間 。
另外我們經常在樹裡面用到位運算,簡單介紹一下:(i
n) (
i>>n)==(⌊i/
2n⌋)
在找子樹的時候,若父親結點編號為
i,則左右子結點分別表示為2i
,2i+
1,而樹中就直接寫為
i<<1和
i<<1|
1(「|」
),而尋找子節點可以表示為
i>>1;
申請結構體的時候,要開到四倍長度空間,直接表示為i<<2;
這裡再說明一下為什麼要開四倍空間
假設我們用乙個陣列來頭輕腳重地儲存乙個線段樹,根節點是
1,孩子節點分別是
2n, 2n+1,
那麼,設線段長為l(即
[1..l+1))
設樹的高度為h,對
h,有:
h(l)={1,1+h(⌈l2⌉)l>=1;
這是乙個很簡單的遞迴式,並用公式逐次代換,就等到
h(l)=k+h(⌈l2k⌉),
其中 k
是滿足2k≥l
的最小值,所以
h(l)=⌈lgl⌉+1.
所以顯然所需空間為
2^h−1=2^(⌈lgl⌉+1)−1 =
2×2^(⌈lgl⌉)−1
=2×2
(l−1
)−1 =
4l−5,
l≥2
(⌈⌉)為向上取整。
線段樹 區間修改(Lazy Tag)
poj3468a problem with integers 傳送門 注意ans可能超出int 懶惰標記 之所以稱為懶惰標記,是因為我們在區間修改時,只修該結點的值,並在節點新增加乙個標記,讓子節點暫時處於不更新的狀態,等我們用到的時候再更新,這樣當我們在查詢的時候,如果我們到了乙個節點p,並且決定...
線段數簡單描述
線段樹的定義 在資訊學競賽中,經常遇到一些與區間操作有關的題目。比如統計若干個矩形的並集,計算若干區間線段的極值及總和等,這時就會用到 線段樹 這種特殊的資料結構。線段樹是一棵二叉樹,記為t a,b 引數a,b表示區間 a,b 其中b a稱為區間的長度,記為l。線段樹t a,b 也可遞迴定義為 若l...
例題 線段數 lazy
1 nkoj 1887 noip2012 day2 借教室 時間限制 40000 ms 空間限制 128000 kb 問題描述 在大學期間,經常需要租借教室。大到院系舉辦活動,小到學習小組自習討論,都需要 向學校申請借教室。教室的大小功能不同,借教室人的身份不同,借教室的手續也不一樣。面對海量租借教...