AC代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
#include <stack>
#include <algorithm>
//#define int long long
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
ll a[maxn],l[maxn],r[maxn];
int main() {
//ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
ll n;
while(scanf("%lld",&n)!=EOF&&(n)) {
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
for(int i=1; i<=n; i++)scanf("%lld",&a[i]);
stack<ll>sl;
for(int i=1; i<=n; i++) { //寻找左边第一个比当前元素小的数
while(!sl.empty()&&a[sl.top()]>=a[i])sl.pop();
if(!sl.empty())l[i]=sl.top();
else l[i]=0;
sl.push(i);
}
stack<ll>sr;
for(int i=n; i>=1; i--) { //寻找右边第一个比当前元素小的数
while(!sr.empty()&&a[sr.top()]>=a[i])sr.pop();
if(!sr.empty())r[i]=sr.top();
else r[i]=n+1;
sr.push(i);
}
ll ans=0;
for(int i=1;i<=n;i++){
ans=max(ans,a[i]*(r[i]-l[i]-1));
//cout<<l[i]<<" "<<r[i]<<" "<<a[i]*(r[i]-l[i]+1)<<endl;
}
printf("%lld\n",ans);
}
}
以前写的AC代码,直接暴力得去找左右第一个最小的数(感觉比上面简洁很多)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=100005;
int n,a[N];
int l[N],r[N];
int main(){
ios::sync_with_stdio(false);
while(cin>>n&&n){
ll res=0;
for(int i=1;i<=n;i++){
cin>>a[i];
l[i]=i;
r[i]=i;
}
for(int i=2;i<=n;i++){
int j=i;
while(j>=1&&a[i]<=a[j])j=l[j]-1;
l[i]=j+1;
}
for(int i=n-1;i>=1;i--){
int j=i;
while(j<=n&&a[i]<=a[j])j=r[j]+1;
r[i]=j-1;
}
for(int i=1;i<=n;i++)
res=max(res,1LL*(r[i]-l[i]+1)*a[i]);
cout<<res<<endl;
}
}