【数据结构】骚操作--单调栈

以cf622(Div.2)的C2题为例讲解一下吧:
**题意:**就是找单峰值。建设大楼,要求每栋楼有限高,而且不允许存在一栋楼两边都有比他更高的楼,要求建成的楼总高度最大。

这里我们引入一个单调栈的东西:花了2小时才算勉强搞明白了(感谢wucstdio大佬)
在这里插入图片描述
这里运用单调栈来做的话,时间复杂度只有O(n),难点在于这个单调栈该如何去写。下面上ac的代码,里面单调栈的部分运用了2次,分别是求上升的单调栈和下降的单调栈。在这里我对上升的单调栈进行了注释,下降的单调栈其本质类似,所以不加赘述。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,a[500005];
int st[500005],num[500005],top;
ll s[500005],pre[500005],suf[500005];
ll ans,pos;
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
	{
		ll now=1;
		while(top&&a[i]<=st[top])  //如果top存在并且当前访问值a[i]小于等于前一个top值 
		{
			now+=num[top];		   //需要更改的长度值+=top所占据的长度	
			top--;				   //把top的位置向前移动 
		}
		st[++top]=a[i];            //更改top的值为当前的a[i] 
		num[top]=now;			   //更改当前top所占据的长度 
		s[top]=s[top-1]+now*a[i];  //当前top的前缀和=前一个top的前缀和+当前的top(a[i])*其所霸占的长度	
		pre[i]=s[top];
	}
	top=0;
	for(int i=n;i>=1;i--)
	{
		ll now=1;
		while(top&&a[i]<=st[top])
		{
			now+=num[top];
			top--;
		}
		st[++top]=a[i];
		num[top]=now;
		s[top]=s[top-1]+now*a[i];
		suf[i]=s[top];
	}
	for(int i=1;i<=n;i++)
	{
		if(ans<pre[i]+suf[i]-a[i])
		{
			ans=pre[i]+suf[i]-a[i];
			pos=i;
		}
	}
	for(int i=pos-1;i>=1;i--)a[i]=min(a[i],a[i+1]);
	for(int i=pos+1;i<=n;i++)a[i]=min(a[i],a[i-1]);
	for(int i=1;i<=n;i++)printf("%d ",a[i]);
	printf("\n");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值