题目大意
n个点在一条直线上,每个点到下一个点需要$t_i$时间,每个点允许通过的时间段是$[u_i,v_i]$。
接下来有m个操作,分为以下三类:
- 问从x点是否能到达y点。
- 将第i个点到下一个点的时间更改为$t_i`$
- 将第i个点的允许通过时间改为$[u_i
,v_i
]$
思路
事实上,我们可以把两个点合并为一个点(注意这是本题非常重要的思想)
对于每个点,我们需要维护这三个值:
允许通过的最晚时间lstArtTime
这个点最快什么时候(即 时间点)到下一个点nxtArTime
这个点到下一个点所需的时间 (注意与上一个做区分)dis
对于$l, r$两个点,假如从$l$点的最早允许通过的点出发,都无法在$r$点最迟允许通过的时间点前到达,那么就无法从$l$走到$r$。(即 l.nxtArTime > r.lstArTime)
如果能到达,我们可以把他们合并为1个点,设它为N。那么我们的任务就是求出N点的数值。
N点的最迟到达时间:首先是不能晚于$l$点的最迟到达时间,其次,还要有足够的时间从$l$走到$r$点,即$r$点的最迟通过时间减去从$l$到$r$点所需的时间。N.lstArTime = max(l.lstArTime, r.lstArTime - l.dis)
N点最快到达下一个点的时间: 即$l$最快到$r$的时间点再加上$r$到下一个点所需的时间,与从$r$最快到下一个点的时间点取一个最大值。
(之所以要比较,是因为从$l$走到$r$,再走到下一个点时,不一定满足 r能够最快到达下一个点时,所需要的条件)。
N.nxtArTime = max(l.nxtArTime + r.dis, r.nxtArTime)
N点到下一个点所需时间,那么就简单了,把$l$到$r$的距离,加上$r$到下一个点的距离。N.dis = l.dis + r.dis。
所以题目就变成如何动态的维护这些点,并且我们已经知道了怎么合并这些点,那么我们就很容易想到利用线段树来维护:
- 每次查询其实就是查询[l,r]之间的点是否合法,因为其中有一个地方无法通过,那么整个区间就会不合法
- 对于修改操作,对于线段树来说就是单点修改。
代码
1 |
|
- 本文作者: 水蓝络合物
- 本文链接: https://miku39393939.github.io/2021/08/03/Journey-among-Railway-Stations/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!