bzoj1345: [Baltic2007]序列問題Sequence(單調棧)

Hanks_o發表於2018-04-07

題目傳送門

解法:
只有我寫的是單調棧嗎?
維護一個單調遞減的棧。
那麼每次進來一個元素x
如果大於棧頂的話。說明棧頂要被消除了。

棧頂與棧頂下一個可以認為是挨在一起的。
x與棧頂可以認為是挨在一起的。
所以比較x與棧頂下一個的大小加到答案裡即可。

跑完一遍之後可能棧還有元素沒消除完。
從棧頂往下慢慢消就行。

程式碼實現:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
int sta[1100000],top,a[1100000];
int main() {
    int n;scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    int top=0;ll ans=0;
    for(int i=1;i<=n;i++) {
        int x=a[i];
        while(x>=sta[top]&&top>0) {
            if(top==1)ans+=ll(a[i]);
            else ans+=min(sta[top-1],x);top--;
        }sta[++top]=x;
    }
    for(int i=1;i<top;i++) ans+=ll(sta[i]);
    printf("%lld\n",ans);
    return 0;
}

相關文章