Codeforces Round #731 (Div. 3)——E. Air Conditioners

原题链接:
在这里插入图片描述
题意:一排方格,有的方格上放了空调,空调温度向两边扩散上升。
求每个位置能够得到的最低温度为多少。

一个位置i的最低温度为min(a[x]+|i-x|),x为空调所在位置。

思路:每个位置左半区间的最低温度和右半区间的最低温度取min。
	维护左区间、右区间两个单调栈。
	栈中存放的是空调的所在位置及其温度。 
	
	左区间:如果当前位置有空调:
			若:当前位置i的温度<=栈顶元素+i-栈顶元素所在位置 
				则栈顶元素永远用不到了,出栈。
	因为后面的位置计算温度时,只是加上了两点间的位置差。
	这样就维护出了一个单调递增的单调栈。
	
	栈底元素就是温度最低的空调温度和位置。

Code:

#include<iostream>
#include<cstring>
using namespace std;

typedef long long LL;
const int N=300010;
int n,m,a[N],b[N];
LL l[N],r[N];
pair<int,int> stk[N];

int main(){
	int T;
	cin>>T;
	
	while(T--)
	{
		cin>>n>>m;
		
		memset(b,0,sizeof b);
		memset(a,0,sizeof a);
		for(int i=1;i<=m;i++) scanf("%d",&b[i]);
		for(int i=1;i<=m;i++) scanf("%d",&a[b[i]]);
		
		int top=0; //左半区间单调栈,求左半区间的最小温度 
		for(int i=1;i<=n;i++)
		{
			if(a[i]){
				while(top>=1&&a[i]<=stk[top].first+i-stk[top].second) top--;  
				stk[++top]={a[i],i};
			}
			
			if(top) l[i]=stk[1].first+i-stk[1].second;
			else l[i]=1e10;
		}
		
		top=0; //右半区间单调栈,求右半区间的最小温度 
		for(int i=n;i>=1;i--)
		{
			if(a[i]){
				while(top>=1&&a[i]<=stk[top].first+stk[top].second-i) top--;
				stk[++top]={a[i],i};
			}
			
			if(top) r[i]=stk[1].first+stk[1].second-i;
			else r[i]=1e10;
		}
		
		for(int i=1;i<=n;i++) cout<<min(l[i],r[i])<<" ";
		cout<<endl;
	}
	return 0;
}

如果有不对或不明白的地方欢迎留言指正!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值