題解【LOJ6515】「雅禮集訓 2018 Day10」貪玩藍月
阿新 • • 發佈:2021-07-10
巧妙的一題
的。
不難發現每個物品的存在時間是一個區間,於是離線可以考慮線段樹分治直接解決。
線上做法比較新奇,用兩個棧模擬雙端佇列。
具體的,維護兩個棧 \(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 即可。
具體實現細節參考 程式碼。