學習筆記·對於線段樹雙重標記的理解

在開始這個話題之前,先簡略說明一下單個lazy標記的作用與意義(想詳盡瞭解的話自行百度一下,有很多)。

lazy標記

  • 作用:降低區間操作的複雜度
  • 意義:lazy標記表示已對當前節點進行了相應修改,而暫時沒有對其左右子節點進行修改
  • 注意:一旦打了標記就要修改當前節點的值,標記只表明未修改其左右子節點,而非未修改當前節點。

雙重標記

一些題有多種區間修改方式,僅用一個標記並不能很好的維護;不過,有了單個標記的思想,就可以將其拓展到多個標記了。

問題引入

多重標記中最常見的就是雙重標記。每個標記的作用、意義都與單個標記時無異。當兩個標記互不影響時,我們只需要按照單個標記那樣一個個處理就好了,這裏不再贅述。不過,當兩個標記互相之間有影響時,會出現一個問題:兩個標記的修改順序是怎樣的呢?以bzoj1798爲例,假設線段樹中的某個節點有一個區間加標記,還有一個區間乘標記,那麼在修改及下放標記時,應該先加後乘,還是先乘後加呢(顯然,這兩種不同的操作會得到不同的解)?

思考

既然順序不清,不妨就定義一個優先級吧!仍以上題爲例:
定義同時存在兩個標記時表示先乘後加。那麼:

  • 對一個無標記的節點打加標記:直接打上加標記,同時更新sum值
  • 對一個無標記的節點打乘標記:直接打上乘標記,同時更新sum值
  • 對一個已有乘標記的節點打加標記:直接打上加標記,同時更新sum值,由於下放標記時先下放的是乘標記,這樣做是正確的
  • 對一個已有加標記的節點打乘標記:問題出現了。如果直接打上乘標記,由於我們先下放的是乘標記,勢必導致加操作和乘操作順序混亂。那怎麼辦呢?其實,只要我們在打乘標記時修正一下加標記就OK了!根據乘法分配律,(+a)×b=×b+a×b ,所以打乘標記b的同時將加標記a乘以b,這樣就保證了標記正確。

總結

當涉及多重標記時,定義出標記的優先級,修改操作時用優先級高(先下放)的修正優先級低(後下放)的來保證標記的正確性。

例題

bzoj1798 [Ahoi2009]Seq 維護序列
luogu3373 【模板】線段樹2
codevs4927 線段樹練習5 題解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章