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 }