【POJ 2796】【單調棧】
阿新 • • 發佈:2018-12-20
一組會WA的資料-_-
10 0 0 0 0 0 0 0 0 0 0
問題轉化成:對於每一個數,求出以它為最小值的最遠左右端點
利用單調棧:維護棧底小,棧頂大的單調棧
每個數入棧的時候記錄左端點(為棧中前一個數的序列位置+1)
出棧的時候記錄右端點(為令它出棧時的數的序列位置-1)
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define N 300005 #define LL long long using namespace std; inline int wread(){ char c(getchar ());int wans(0),flag(1); while (c<'0'|| c>'9'){if (c=='-') flag=-1;c=getchar ();} while (c>='0' && c<='9'){wans=wans*10+c-'0';c=getchar ();} return wans*=flag; } int n; int sav[N]; struct node{ int zhi,pos; node() {}node(int x,int y):zhi(x),pos(y){} }S[N]; int top; int ml[N],mr[N]; LL sum[N]; int main (){ n=wread(); for (int i(1);i<=n;++i) sav[i] = wread(); for (int i(1);i<=n;++i) sum[i] = sum[i-1]+(LL)sav[i]; S[++top] = node(sav[1],1) ; ml[1]=1; int r(1); while (r!=n){ r++; if (sav[r]>S[top].zhi) ml[r]=S[top].pos+1,S[++top] = node(sav[r],r); else if (sav[r]==S[top].zhi) ml[r]=ml[S[top].pos],S[++top] = node(sav[r],r); else { while (S[top].zhi>sav[r] && top>=1) mr[S[top].pos]=r-1,top--; if (!top) S[++top]=node(sav[r],r),ml[r] = 1; else { if (S[top].zhi==sav[r]) ml[r] = ml[S[top].pos],S[++top] = node(sav[r],r); else ml[r] = S[top].pos +1,S[++top] = node(sav[r],r); } } } while (top!=0) mr[S[top].pos] = n,top--; LL ans(-1);int pr(0); for (int i(1);i<=n;++i) ans < ((LL)sav[i]*( sum[mr[i]] - sum[ml[i]-1] )) ? (pr=i,ans=((LL)sav[i]*( sum[mr[i]] - sum[ml[i]-1] ))) : ans=ans; printf("%lld\n",ans); printf("%d %d\n",ml[pr],mr[pr]); return 0; }