当时我的第一想法也是用单调栈,但是被我写炸了;我也不知道错在哪里;
看了大神的写法,用数组模拟的;
记录下单调递增栈的下标,以及每个数字作为最小值的最左边的位置。
当有数据要出栈的时候,说明栈里的数据已经不是最小了,右端点就是当前位置-1,那么就可以计算栈顶的元素所作的贡献;出栈完后,当前这个数字,他的最左边就是栈顶所能到达的位置;入栈;
#include <bits/stdc++.h> using namespace std; const int maxn = 100000 + 5; int a[maxn]; int stacks[maxn]; long long sum[maxn]; int lef[maxn]; int main() { freopen("feelgood.in","r",stdin); freopen("feelgood.out","w",stdout); int n; scanf("%d",&n); memset(sum,0,sizeof(sum)); memset(lef,0,sizeof(lef)); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); sum[i] = sum[i-1] + a[i]; } a[++n] = -1; int top = 0; long long ans = -1; int ansl = 0,ansr = 0; for(int i=1;i<=n;i++) { if(top==0||a[i]>a[stacks[top-1]]) { stacks[top++] = i; lef[i] = i; continue; } if(a[i]==a[stacks[top-1]]) continue; while(top>=1&&a[i]<a[stacks[top-1]]) { top --; long long tmp = (long long)a[stacks[top]]*(sum[i-1]-sum[lef[stacks[top]]-1]); if(tmp>ans) { ansr = i-1; ansl = lef[stacks[top]]; ans = tmp; } } lef[i] = lef[stacks[top]]; stacks[top++] = i; } printf("%lld\n%d %d\n",ans,ansl,ansr); return 0; }