有很多的方法過這題,以下介紹三種方法,主要思路是將序列反轉(其實不反轉也沒什麼),然後去找第i個元素左邊靠最右的比這個元素大的位置j,那麼i-j+1就是第i個元素對應的解。
第一種方法:利用線段樹動態更新,完成上部分的查詢,複雜度o(nlogn)。
對線段樹處理這類問題的方法就不詳細說明了,想要了解的,看這篇文章
我的**:
第二種方法:利用乙個單調棧,棧內維護乙個遞減的區間,記錄在此元素之前比其大的元素序列的下標。新的元素入隊,如果棧頂元素大於這個入隊元素,那麼結果就加上這個元素的下標減去棧頂元素下標再減去1,否則棧頂元素出棧,以此類推。演算法複雜度是o(n)的。
演算法實現其實很簡單,只要維護乙個棧,用top表示棧頂下標就可以了。
我的**:
第三種方法:利用並查集的思路直接做。記錄r[i]表示第i個元素可以到達的最右邊的下標,那麼每次利用下面的方式壓縮路徑:
r[i]=i;
while(h[i]>h[r[i]+1])r[i]=r[r[i]+1];
細節處理看我的**,演算法複雜度是o(n*α(n))的。
我的**:
三個演算法比較:
對於第乙個演算法肯定是最慢的,畢竟o(nlogn)的時間複雜度加上線段樹的較大常數,和下面兩個o(n)或者近似o(n)的演算法來比,會遜色很多。
從後兩個演算法執行時間上看,o(n*α(n))的第三種演算法反而更快,可能是我單調棧常數太大了,或者我的序列反轉過的原因。
POJ 3250 單調堆疊
其實今天是第一次聽說這個資料結構。順便ac了一道題目 所以這個堆疊顯然會滿足一些條件 1.對於所有當前步驟壓入堆疊的元素e,棧中的其餘元素都是 遞增 或遞減 的大於 或小於 e 2.對於彈出的所有元素,一定全都 小於或大於e 這個題目第一眼看到應該是乙個 n 2 的暴力搜尋,但是明顯如果用暴力搜尋的...
POJ 3250 單調棧模板
題意 從左右給你n頭都面向右牛的高度,每頭牛能被左邊的牛看到當且僅當自己的身高比他低且中間沒有障礙物 求每頭牛能看到的牛數量之和 include include include include include include include include include include inclu...
poj3250(單調棧模板題)
題意 求序列中每個點右邊第乙個 自身的點的下標。思路 簡單介紹單調棧,主要用來求向左 右第乙個小於 大於自身的下標,直接求的話複雜度為o n2 而單調棧只有o n 利用好單調棧十分有用。乙個元素向左遍歷的第乙個比它小的數的位置就是將它插入單調棧時棧頂元素的值,若棧為空,則說明不存在這麼乙個數。然後將...