好像是单调栈的模板题了,但是稍稍改动了一下也就是柱状图的宽度可能会变。
题解:这个题数据范围1e6,如果我们暴力解,肯定会超时,那么我们这里用单调栈。
单调栈,分为单调递增栈和单调递减栈,这个题用的是单调递增栈。
首先我们枚举每个柱子的高度,枚举时,对于这个柱子先不做计算,而是把他放进栈内。
因为要保证这个栈是单调递增的,所以我们在放进这个柱子的时候,要判断这个柱子是不是比栈内元素都要大,如果都大的话,我们就可以直接把他放进栈内,但是如果小的话,我们就要让一些栈内元素出栈,直到栈的元素不比当前元素小为止。
在出栈的过程中,我们对于当前出栈柱子做计算。
因为栈元素是单调递增的,所以我们保证在出栈的这个元素到(当前枚举到元素位置-1)的范围内,高度都是严格大于出栈的这个元素的。计算即可。
对于它的宽度,我们用一个前缀和进行处理即可。
/*Keep on going Never give up*/ #pragma GCC optimize(3,"Ofast","inline") #include <bits/stdc++.h> const int maxn = 1e6+10; const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int mod = 100000000; using namespace std; stack<int> s; ll w[maxn],a[maxn]; int main() { int n; cin>>n; for(int i=1;i<=n;i++){ scanf("%lld",&w[i]); w[i]=w[i-1]+w[i]; } for(int i=1;i<=n;i++) scanf("%lld",&a[i]); s.push(0); ll ans=0; for(int i=1;i<=n;i++){ while(a[i]<a[s.top()]){ int temp=s.top(); s.pop(); ans=max(ans,a[temp]*(w[i-1]-w[s.top()])); } s.push(i); } cout<<ans<<endl; return 0; }