题解:AT_abc359_e [ABC359E] Water Tank

Idea

对于一个柱子无非只有两种情况:

  • 它比之前每一个柱子高度低。
  • 它是目前最高的。

如果比一个柱子高度低,由题意模拟,我们找到最靠右的比它高的柱子,把答案加上即可。

设那个找到的柱子坐标为 xx,现在模拟到了 ii,则下一个答案答案应为:(ix+1)hi+(ansi1)+1=(ix+1)hi+ansi(i-x+1)h_i+(ans_{i}-1)+1=(i-x+1)h_i+ans_i

如果它是最高的,则前面所有的都要填满,则下一个答案是 hi(i+1)+1h_i(i+1)+1

实现起来,为了找到最靠右的比它高的柱子,可以使用单调栈。如果一根柱子在另一个柱子左边还比它矮,它一定没用,扔掉就行了。一遍遍的枚举,最后剩下的一定是最靠右的比它高的柱子。

每一个柱子只会进出栈一次,因此时间复杂度是 O(n)\operatorname{O}(n)

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;
}
posted @   Weslie_qwq  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示