【筆記】線段維護單調棧

CloudWings發表於2024-08-07

【筆記】線段維護單調棧

維護單調棧的資訊可以包括:

  1. 單調棧的大小;
  2. 單調棧裡面元素的權值(可以和鍵值不一樣)的極值/和。

1 核心思想

(以維護嚴格單增的單調棧為例,單減同理。

首先線段樹內會維護區間最大值 \(mx\),和區間的答案 \(ans\)

定義一個函式:\(calc(p,x)\) 表示線上段樹的 \(p\) 節點,刪去區間內小於等於 \(x\) 的元素,剩下構成的答案。

那麼 \(ans(p)=ans(ls)+calc(rs,mx(ls))\)。(這個 \(+\) 是合併的意思,不是真正意義上的加法。

考慮怎麼算 \(calc(p,x)\)

分討一下:

  1. 區間長度為 \(1\):略;

  2. 如果 \(mx(ls)<x\)\(calc(p,x)=calc(rs,x)\)

  3. 如果 \(mx(ls)\ge x\)\(calc(p,x)=calc(ls,x)+calc(rs,mx(ls))\)

    這樣乍看上去好像並沒有什麼用,還是 \(O(n)\) 的,但實際上變化就在於後面是 \(calc(rs,mx(ls))\),而不是 \(calc(rs,x)\)

    相對於 \(x\)\(mx(ls)\) 可以視為定值,因為我們每次更新 \(mx\) 的時候,就可以同步算出新的 \(calc(rs,mx(ls))\),然後儲存到一個變數裡面。

這樣的話,我們就保證了 \(calc(p,x)\),可以在 \(O(\log n)\) 的時間複雜度內求解。

而每次 push_up 的時候都要呼叫一遍,所以總的時間複雜度就是 \(O(n\log^2 n)\)


2 例題

2.1 樓房重建

維護單調棧長度的板子。

相關文章