LA 4108 SKYLINE 线段树

LA 4108

题意:T组数据,每次输入n,接下来n次操作,每次输入 L R H,表示建筑物的左边界,右边界,和高度,要求计算这次输入的建筑物覆盖度,比如,原来1-3的最高高度是3,3-5的最高高度是4,5-6的最高高度是5,如果输入1 6 4,则这次覆盖度是5-1=4,并且更新这个区间的最高高度,求n次操作的总覆盖度。

比较容易的一个区间更新并且求区间的线段树,设max[ o ]为o这个节点所含区间中的最大高度,设set[ o ]为o这个区间是否覆盖,如果覆盖设为1,没覆盖为0,每次跟新一个区间的高度,都把这个区间的set[ o ]设为1,如果某个节点的set值为1,那么要更新其子节点时,把该节点set值和max值传递到其子节点,并把该节点的set值0。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=3e5+5;
const int inf=1e8;
int n,ql,qr,h,_max[maxn],_set[maxn],ans;
void init()
{
	ans=0;
	for(int i=0;i<maxn;i++)
	_max[i]=_set[i]=0;
}
void maintain(int o,int ls,int rs)
{
	int t=max(_max[ls],_max[rs]);
	_max[o]=max(_max[o],t);	
}
void pushdown(int o,int ls,int rs)
{
	if(_set[o])
	{
		_set[o]=0;
		_set[ls]=_set[rs]=1;
		_max[ls]=_max[rs]=_max[o];
	}
}
void update(int L,int R,int o)
{
	if(L>=ql&&R<=qr&&_max[o]<=h)
	{
		_set[o]=1;
		_max[o]=h;
		ans+=R-L+1;
		return;
	}
	if(_max[o]>h&&_set[o]==1)
	return;
	int ls=o*2,rs=o*2+1;
	int m=(L+R)/2;
	pushdown(o,ls,rs);
	if(ql<=m)	
	update(L,m,ls);
	if(qr>m)		
	update(m+1,R,rs);
	maintain(o,ls,rs);
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int i;
		scanf("%d",&n);
		init();
		while(n--)
		{
			scanf("%d%d%d",&ql,&qr,&h);
			qr--;
			update(1,100000,1);
		}
		printf("%d\n",ans);
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长沙橘子猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值