这题一看就是离散化加线段树,但是怎么建树确实没想出来。不过看到每个bus的时间点都不同,可能会有一点提示。
后来仿照一个神牛的代码写了一下 。
思路是这样的:首先,将bus和person的起止坐标一并取出到一个数组中,然后离散化之,对每个人每个bus都记录一下id,然后就是把这些坐标排序,去重,数组大小数就是线段树的长度了, 就可以建树了。然后用二分查找把bus和人的起止坐标在数组中的位置找出,记录下来,替换掉原来的坐标,然后将人和bus按照起点坐标从左到右进行结构体排序。
然后就是线段树的部分,线段树中每个结点存储的信息是一个集合,每个元素是bus的时间和id形成的pair。建树的时候,刚开始每个结点没有bus覆盖,所以时间就是无限大,id也就是-1了。然后按刚才排好序的结构体数组枚举人,对每个人,将出发站点不在人右边的bus的信息插入线段树中,因为只有这样的bus才有可能将人带到目的地,并且,由于bus也是排好序的,所以对于一个人来说,如果他前边的人所能上的bus都插入了,那么他也不用再重复插入这些bus,这样的好处很明显,如果全部插入后进行查询,会造成每个结点的set中元素很多,从而导致超时,因为即使这样优化,最终也接近TLE。而插入的方法很简单,将所有包含bus终点的区间均插入该bus的时间和id即可。
对每个人来说,插入完毕后就进行查询了,查询的区间必然是从这个人要到的地方一直到线段树末尾,然后对任何其子区间中包含的bus时间和id,取最小值即可
总体来说 ,复杂度是n log(n)log(n)级别的
其中多出来的一个log(n)是set的insert和lower_bound函数带来的。
/*
ID: sdj22251
PROG: subset
LANG: C++
*/
#include
#include
#include
#include