1. 程式人生 > >單調棧應用

單調棧應用

%d urn typedef ostream stack 給定 else turn txt

 1 /*
 2   題意:POJ2796 給定一個長度為n的數組,求sum(a[i])*min(a[i)最大的一段區間。
 3   思路:枚舉每個a[i],求最左邊和最右邊的距離。利用單調棧求左右區間
 4   時間:2018.07.17
 5 */
 6 // #include <bits/stdc++.h>
 7 #include <cstdio>
 8 #include <iostream>
 9 using namespace std;
10 
11 typedef long long LL;
12 const int MAXN=100005;
13 const LL MOD7 = 1e9+7
; 14 15 int a[MAXN]; 16 int n; 17 LL sum[MAXN]; 18 int L[MAXN]; 19 int R[MAXN]; 20 int Stack[MAXN]; 21 int top; 22 23 void printStack() 24 { 25 for (int i=0;i<top;++i) printf("%d ",Stack[i]);printf("\n"); 26 } 27 28 void init() 29 { 30 top=0; 31 for (int i=1;i<=n;++i) 32 { 33 while
(top && a[Stack[top-1]]>=a[i]) --top; 34 // printf("%d: ",i); 35 // printStack(); 36 if (!top) L[i]=1; 37 else L[i]=Stack[top-1]+1; 38 Stack[top++]=i; 39 } 40 top=0; 41 for (int i=n;i>=1;--i) 42 { 43 while (top && a[Stack[top-1
]]>a[i]) --top; 44 if (!top) R[i]=n; 45 else R[i] = Stack[top-1]-1; 46 Stack[top++]=i; 47 } 48 // for (int i=1;i<=n;++i) printf("L[%d]=%d\tR[%d]=%d\n",i,L[i],i,R[i]); 49 } 50 51 int main() 52 { 53 #ifndef ONLINE_JUDGE 54 freopen("test.txt","r",stdin); 55 #endif // ONLINE_JUDGE 56 scanf("%d",&n); 57 for (int i=1;i<=n;++i) 58 { 59 scanf("%d",&a[i]); 60 sum[i]=sum[i-1]+a[i]; 61 } 62 init(); 63 LL ans=-1; 64 int l,r; 65 for (int i=1;i<=n;++i) 66 { 67 LL tmp = (LL)a[i]*(sum[R[i]]-sum[L[i]-1]); 68 if (tmp>ans) 69 { 70 ans = tmp; 71 l=L[i]; 72 r=R[i]; 73 } 74 } 75 printf("%lld\n",ans); 76 printf("%d %d\n",l,r); 77 return 0; 78 }

單調棧應用