题意:求所有区间的最小值
思路:维护一个单调递增栈 , 利用单调栈求出以当前数a[i] 为最小值 的区间的长度,每次更新最小值。
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
#define read(x) scanf("%lld",&x)
#define debug puts("^^^^^^^")
using namespace std;
const int maxn=1e5+5;
typedef long long LL;
struct node{
LL num;
LL next,pre,id;
};
LL n;
LL a[maxn];
LL sum[maxn];
int main() {
while(read(n) != EOF && n) {
stack<node> s;
memset(sum,0,sizeof(sum));
for(int i=1;i<=n;i++) {
read(a[i]);
sum[i]=sum[i-1]+a[i];
}
node tmp;
tmp.num=a[1];
tmp.next=tmp.pre=1;
tmp.id=1;
LL ans=-1;
LL s1=-1;
s.push(tmp);
LL x=0,y=0;
for(int i=2;i<=n;i++) {
node tmp1;
tmp1.num=a[i];
tmp1.pre=tmp1.next=1;
tmp1.id=i;
while(!s.empty() && tmp1.num <= s.top().num) {
tmp=s.top();
s.pop();
if(!s.empty()) {
s.top().next+=tmp.next;
}
tmp1.pre+=tmp.pre;
ans=tmp.num*(sum[tmp.id+tmp.next-1]-sum[tmp.id-tmp.pre]);
if(ans >= s1) {
s1=ans;
x=tmp.id-tmp.pre+1;
y=tmp.id+tmp.next-1;
}
}
s.push(tmp1);
}
while(!s.empty()) {
tmp=s.top();
s.pop();
if(!s.empty()) {
s.top().next+=tmp.next;
}
ans=tmp.num*(sum[tmp.id+tmp.next-1]-sum[tmp.id-tmp.pre]);
if(ans >= s1) {
s1=ans;
x=tmp.id-tmp.pre+1;
y=tmp.id+tmp.next-1;
}
}
printf("%lld\n%lld %lld\n",s1,x,y);
}
}