http://poj.org/problem?id=2796
题意:要求找一个区间的价值最大,区间价值定义为,区间和乘上区间最小值。
做法:直接找到以每一个值为最小值的区间,然后遍历一遍就完了。
此题还有一些坑,比如最大值为0,以及long long等
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=5e5+10;
int n,m,a[N];ll sum[N];
int que[N],head,tail,id[N];
int l[N],r[N];
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
sum[0]=0;
for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
stack<int>st;
for(int i=1;i<=n;i++) r[i]=n+1;
for(int i=1;i<=n;i++)
{
while(!st.empty()&&a[st.top()]>a[i])
{
r[st.top()]=i;
st.pop();
}
st.push(i);
}
while(!st.empty()) st.pop();
for(int i=1;i<=n;i++) l[i]=0;
for(int i=n;i>=1;i--)
{
while(!st.empty()&&a[st.top()]>a[i])
{
l[st.top()]=i;
st.pop();
}
st.push(i);
}
long long ans=-1;
int ansl,ansr;
for(int i=1;i<=n;i++)
{
ll t=(long long)a[i]*(sum[r[i]-1]-sum[l[i]]);
if(ans<t)
{
ans=t;
ansl=l[i]+1;
ansr=r[i]-1;
}
}
printf("%lld\n%d %d\n",ans,ansl,ansr);
}
return 0;
}