题解:AT_abc359_e [ABC359E] Water Tank
Idea
对于一个柱子无非只有两种情况:
- 它比之前每一个柱子高度低。
- 它是目前最高的。
如果比一个柱子高度低,由题意模拟,我们找到最靠右的比它高的柱子,把答案加上即可。
设那个找到的柱子坐标为 ,现在模拟到了 ,则下一个答案答案应为:。
如果它是最高的,则前面所有的都要填满,则下一个答案是 。
实现起来,为了找到最靠右的比它高的柱子,可以使用单调栈。如果一根柱子在另一个柱子左边还比它矮,它一定没用,扔掉就行了。一遍遍的枚举,最后剩下的一定是最靠右的比它高的柱子。
每一个柱子只会进出栈一次,因此时间复杂度是 。
Code
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
int h[200005];
long long ans[200005],ju[200005];
int st[200005],id[200005];
int top=200001;
signed main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>h[i];
ans[0]=1;ju[0]=h[1];
st[0]=2147483647;
st[1]=h[1]; id[1]=0;
for(int i=1;i<=n;i++){
ans[i]=ju[i-1]+1;
while(top!=0&&st[top]<=h[i+1])top--;
id[++top]=i;
st[top]=h[i+1];
int t=top-1;
if(t!=0)ju[i]=ju[id[t]]+(i-id[t])*h[i+1];
else ju[i]=h[i+1]*(i+1);
}
for(int i=1;i<=n;i++)cout<<ans[i]<<' ';
return 0;
}

浙公网安备 33010602011771号