1. 程式人生 > 其它 >題解【LOJ6515】「雅禮集訓 2018 Day10」貪玩藍月

題解【LOJ6515】「雅禮集訓 2018 Day10」貪玩藍月

巧妙的一題

題面

不難發現每個物品的存在時間是一個區間,於是離線可以考慮線段樹分治直接解決。

線上做法比較新奇,用兩個棧模擬雙端佇列。

具體的,維護兩個棧 \(stkl\)\(stkr\),在開頭和結尾插入刪除就直接在這兩個棧中分別 push 和 pop。

如果出現刪除時某個棧空了,那麼直接暴力重構這兩個棧使得這兩個棧大小之差最小。

這樣做為什麼是對的呢?

\(w\) 為兩棧的大小之差,那麼一次正常的插入刪除只會讓 \(w\) 變化 \(1\),而重構平均分配的操作會用 \(\cal{O}(w)\) 的複雜度使 \(w\) 變成 \(0\)\(1\)。均攤下來複雜度是 \(\cal{O}(m)\)

的。

在操作過程中順便維護一下揹包陣列 \(dpl\)\(dpr\)

求答案時維護一個數組 \(mxr_{i,j}\) 表示 \([i,i+2^j]\) 的範圍中 \(dpr\) 的最大值,列舉 \(stkl\) 中選多少個然後分類討論求一下 max 即可。

具體實現細節參考 程式碼