[BZOJ2957]楼房重建

本文介绍了一道关于维护单调序列的问题,通过使用线段树进行区间查询与合并,解决了在一系列操作后能够被看到的位置数量问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

貌似已经很久没有写blog了的说……一直在用为知笔记都快忘记博客了emm
这次先拿这样一道水题来写一下吧,这个思想好像很常用,最近这几天已经遇到很多次了。

题意

一个长度为nn的序列wi表示楼房高度,初始都是00,有m个操作,每次单点修改一个位置的高度,可以变成正的也可以变成负的,问有多少个位置能够在每次修改后被看到(也就是说,其最高点与原点连线上没有其他楼房)。
0n,m1000000≤n,m≤100000

分析

题意非常明显,考虑维护每个高度对于原点的一个斜率ki=wiiki=wii,这里要求的就是问有多少个kiki大于前面所有数。这相当于就是在维护一个上升的单调序列,我们可以考虑用线段树来维护这个。
考虑每次直接查询整个区间,那么我们考虑对于某一个区间,我们可以记下这个区间只算自己内部应该有的答案,那么下面考虑一下怎么区间合并。考虑当前区间称为[l,r][l,r],那么左边的区间[l,m][l,m]的答案肯定是可以直接算进来的,而右边的区间的答案则需要考虑加入左边区间的限制的情况下的新的答案。首先显然如果右区间斜率最大值小于等于左边最大值,那么右区间肯定没有贡献。
如果大于最大值,我们考虑这时怎么做。我们需要在右区间进一步分出其两个子区间来计算,同样的思想,我们只需要考虑一下左子区间会不会将这个左区间的影响“屏蔽”即可。如果左子区间最大值小于等于左区间最大值,就相当于左子区间整个没用了,我们递归处理右子区间;反之,说明左子区间里面存在至少一个点(例如那个最大值),会将左区间的影响全部“屏蔽”,那么递归处理左子区间即可。于是右区间的答案在后一种情况下就是整个区间的答案减去左子区间,因为单纯右子区间的答案并没有考虑左子区间的影响。
实际实现中,我们可以考虑写成“该节点对于某个值在最前面的答案”的查询。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值