STL 必定要學好 必定要學好,必定要學好!!!node
題目連接:https://www.luogu.org/problemnew/show/P1823spa
咱們須要單向查找;用單調棧;code
思路:
維護一個身高單調遞減的棧,若是下一個比上一個插入的矮,就直接進棧,若是如今插入的比上一個高,咱們就要更新答案的值;blog
由於如今要插入的人會擋住前面比他矮的人,因此前面比他矮的人就不能再看見之後的人了;get
固然還要記錄前面和他同樣高的人的個數,由於和他同樣高的人是能夠看見他後面的人的(題目中是大於沒有等於)string
由於咱們維護的是右端點的值,因此前面的矮人就直接彈出;it
代碼io
#include<cstdio> #include<cstring> #include<stack> #include<algorithm> using namespace std; const int maxn=500050; stack <int> s;//單調棧 int n,x,ans; int a[maxn]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { int t=1;//記錄和他身高同樣的人的個數 scanf("%d",&x); while(s.size()&&x>=s.top())//棧中還有人而且有人比他矮或等高 { if(x==s.top()) t++; ans++;s.pop();//由於不彈出就不能查看上一個值,因此即便等高也要彈出 } if(s.size()) ans++;//若是前面有人比他高,那麼他們兩我的也能互相看到 while(t--) s.push(x);//將全部不應彈出的等高的人加入棧 } printf("%d",ans); return 0; }
對不起,TLEclass
顯然咱們處理等高的人的時候浪費了大把的時間,因此咱們能夠把前面和他等高的人的貢獻直接加到如今要插入人的身上top
用結構體就好了
代碼
#include<cstdio> #include<cstring> #include<stack> #include<algorithm> using namespace std; const int maxn=500050; struct node { int h;//高度 long long num;//前面等高人的個數 }; stack <node> s; int n,x; long long ans; int a[maxn]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&x); node p=(node){x,1};//記錄當前和他等高的人是本身 while(s.size()&&x>=s.top().h) { if(x==s.top().h) p.num+=s.top().num; ans+=s.top().num;s.pop(); } if(s.size()) ans++; s.push(p); } printf("%lld",ans); return 0; }
STL 不會,手寫兩行淚;