这道题本质上就是找左右边第一个比他小的数在哪,作为他的边界
因为数据范围比较大,所以我们考虑用到单调栈来写
可以先求左边,再反转数组重求,也可以直接到着求右边
如果反转数组,那么就要注意最后相减的表达式
#include<iostream> #include<cstring> #include<cstdio> #include<map> #include<algorithm> #include<queue> #include<set> #define ull unsigned long long using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=1e5+10; int l[N],r[N]; int q[N]; int h[N]; int n; void get(int s[]){ int i; int tt=0; for(i=1;i<=n;i++){ while(h[q[tt]]>=h[i]) tt--; s[i]=q[tt]; q[++tt]=i; } } int main(){ int i; while(cin>>n,n){ int i; h[0]=-1; for(i=1;i<=n;i++){ scanf("%d",&h[i]); } get(l); reverse(h+1,h+1+n); get(r); int j; ll ans=0; for(i=1,j=n;i<=n;i++,j--){ ans=max(ans,h[i]*(n+1-l[j]-r[i]-1ll)); } cout<<ans<<endl; } return 0; }