JOISC 2016 回転壽司

cxqghzj發表於2024-04-03

題意

給定一個有 \(n\) 個點的環,環上每個點各有一個權值 \(A_i\)

給出 \(m\) 個詢問,每次詢問給定整數 \(x\)

你需要進行如下操作:

for (int i=l;i<=r;i++) if(a[i]>x) swap(a[i],x);

對於每次詢問,回答操作後 \(x\) 的最終取值。

\(1 \le n \le 4 \times 10 ^ 5, 1 \le q \le 2.5 \times 10 ^ 4\)

Sol

集中注意力,不難發現每次 \(x\) 的最終取值一定為:

\[x = \max_{i = l} ^ r a_i \]

考慮一個弱化版的問題,每次詢問 \(l = 1, r = n\)

注意到我們並不關係 \(a\) 到底長什麼樣子,我們只需要知道當前的最大值,並且需要動態維護。

直接上個堆就做完了。

於是我們的思路就很明確了,對於 \(a\) 分塊。

對於每個塊維護一個堆,用來處理當前的詢問。

問題在於散塊該如何維護?

注意到我們需要知道散塊每個位置上的值,這明顯是不好做的。

我們需要一些更強的結論。

如果對於一個區間插入若干值,插入順序不影響序列最終的長相

注意到當前塊 \(a_l, a_{l + 1}, ..., a_{r}\),每次彈出的最大值是固定的。

顯然,對於當前被修改過的下標的集合 \(p\)\(p_{a_i}\) 滿足單調不降。

所以,順序不影響長相。

具體地,在修改時將 \(x\) 扔進小根堆 \(q\),重構時考慮暴力列舉這個塊的所有點,先將當前點加入堆,然後將堆頂元素放在當前位置。

這樣就做完了。

時間複雜度:\(O(n \sqrt n \log n)\)

相關文章