維護乙個序列
,支援單點修改,定義乙個位置
i 的權值為ai
i,要求實時回答最長棧的長度(也就是說從開頭依次選入,若棧為空或大於已選擇的最後乙個元素則選擇,小於等於則捨棄)。
n<
400,
000
問題主要是難在如何維護這個最長棧。
題解用了比較巧妙的方法,因為它並沒有「維護「這乙個序列。它是類似於樹分治這樣每一次通過lo
g2n 的時間算出當前的答案。
顯然題目與ai
本身沒有太大的關係,我們直接用ai
i 來做這個位置的值。
主要根據以下的思路。
我們利用線段樹來維護這個序列,對於乙個區間我們維護它的最大值以及這個區間的最長棧的長度。
考慮如何維護這兩個值,最大值的維護比較簡單,主要是維護後者,記其為f(
l,r)
。當前區間的最長長度不妨可以理解為左區間的最長長度加上右區間的最長長度,並且考慮左區間對右區間的影響。
考慮右區間的權值在受到左區間的影響後會剩下什麼,設過程ca
lc(x
,l,r
) 表示求區間[l
,r) (初始是右區間), 它前面的元素的最大值(初始是左區間的最大值)為
x 時,它對大區間的貢獻是多少。
於是這個問題就解決了,時間複雜度為o(
nlog
2n)。
其實這種實時計算答案的思路在樹分治裡面就已經見過了,反倒是在序列上比較少見,值得記住的一道題。
2957 樓房重建
題目鏈結 題目大意 數軸上有n座樓,初始高度為0,每次可以改變某棟樓的高度,求每次改變高度之後從原點可以看到幾棟樓 題解 記每棟樓樓頂與原點連線的斜率,那麼一棟樓可見當且僅當前面所有樓的斜率都小於這棟樓 分塊 塊內維護特殊的lis,4 1 2 3 5 那麼維護的序列就是4 5 塊內暴力修改,查詢的時...
清華集訓 2013 樓房重建(線段樹)
題意轉化 動態維護乙個單調棧,支援單點修改,整體查詢單調棧長度。使用線段樹。對於每個節點,維護 ma x ro ot max roo t 表示區間最大值,cn t ro ot cnt roo t 表示區間中的單調棧的長度。在自底向上 maintain 的時候,cn t ro ot cnt lson ...
bzoj 2957 樓房重建
小a的樓房外有一大片施工工地,工地上有n棟待建的樓房。每天,這片工地上的房子拆了又建 建了又拆。他經常無聊地看著窗外發呆,數自己能夠看到多少棟房子。為了簡化問題,我們考慮這些事件發生在乙個二維平面上。小a在平面上 0,0 點的位置,第i棟樓房可以用一條連線 i,0 和 i,hi 的線段表示,其中hi...