單調棧,就是一個棧,不過棧內元素保證單調性。即,棧內元素要麼從小到大,要麼從大到小。
而單調棧維護的就是一個數前/後第一個大於/小於他的數。數組
例題:P5788 【模板】單調棧
例題就是一個求每一個數後第一個大於他的數。spa
那麼重點來了:怎麼作!面對這樣的數據,很差下手。那麼咱們把她轉化一下:有\(n\)我的,每一個人向右看,求她看到的第一我的。
看圖:
經過觀察,咱們會發現,在她後面的,比她矮的,必定會被她遮住。那麼,這個點就沒用了。而根據現實生活和剛纔的推斷,咱們看到的人確定是一個比一個高的,而沒看到的,留着也沒用,直接扔了QwQ。那麼,這就是符合單調性的。再看,那些沒用的人何時扔掉?固然是遇到比她高的人了。那麼就能夠一個一個地走掉,並且確定是在已經判斷過的人的前面(中間和後面的在以前就走掉了),因此就直接從前面彈出。咦?這不就像一個棧嗎?沒錯,這就是單調棧的實現方法。code
再概括一下:blog
從後往前掃get
對於每一個點:io
因爲是從前日後輸出,還要把答案放到一個數組裏。模板
放代碼:class
#include<cstdio> #include<stack> using namespace std; int n,a[3000005],f[3000005];//a是須要判斷的數組(即輸入的數組),f是存儲答案的數組 stack<int>s;//模擬用的棧 int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=n;i>=1;i--) { while(!s.empty()&&a[s.top()]<=a[i]) s.pop();//彈出棧頂比當前數小的 f[i]=s.empty()?0:s.top();//存儲答案,因爲沒有比她大的要輸出0,因此加了個三目運算 s.push(i);//壓入當前元素 } for(int i=1;i<=n;i++) printf("%d ",f[i]);//輸出 return 0; }
完 結 辣!方法