题目大意
给出一维坐标系上的n个点,和n个点所代表的区间,其中第一个点坐标为0。对于任意两个点,右边的点可以到达左边(包括坐标相同)当且仅当满足它们代表的区间有重合且距离不超过一个给出的值L。求编号2——n的点到第一个点的最短距离。无法到达输出-1
对于50%的数据,3≤n≤20000;
对于100%的数据,1≤n≤250000,0≤xi,yi,li≤2000000000,1≤l≤2000000000,xi≤yi
最初的思路
在1右边的点到达1,也相当于从1出发到其它的点。所以跑个单源最短路是可行的,但是数据范围较大,加上两点连边的数量也可能很大,所以最短路会超时。
50分算法
这道题时间限制比较宽,所以O(n^2)的单源最短路是可以过掉的。对当前的点枚举其它点,判断区间是否重合即可。因为两点之间的距离为1,我们可以直接打个bfs,设 dis[i] 为1到i的最短距离,转移方程显然
满分算法
n达到250000的情况,bfs会超时。这时我们考虑用数据结构来维护区间。
那么我们可以给区间以li为关键字排序,然后进行插入、查询、删除。
考虑两个问题:
1. 如何用数据结构插入并查询区间;
2. 如何用数据结构删除一个区间;
如果枚举的区间的坐标是从小到大的,那么显然,它们的答案也是不递减的,所以对于线段树的每个节点都开个单调队列来维护最小值,删除时直接删掉队首。
对于一个 1..n 的范围,在线段树中插入、询问、删除一个区间 l..r ,区间 l..r 最多会被分成 log(n) 块。所以单调对列的总大小不会太大。
考虑一个实现上的问题。如何插入区间能使与它有重合的区间查询到它。
当插入操作到达一个线段树的区间