题意:50000个点的树,每个点有一个人,每个人会跑到离自己初始点距离最远的点上,这个距离为distance[i]。给你500个查询,对于每个查询Q,找一段连续编号的人,比如[left,right],满足 max( distance[i] i∈[left,right] ) – min( distance[i] i∈[left,right] ) ≤ Q,并且使得length=right-left+1要最大,求这个最大的length
法一:关键是O(1)的RMQ。。。。
分析:求distance[i]数组(代码中的d),可以用搜边的方法来解决,然后线性维护一个队列,使得队列中的最大值 – 最小值 ≤ Q,之后,会有一个新的distance[i]插到队列的头部,这样会打破“最大值 – 最小值 ≤ Q”的规则,此时要从队列末尾弹出元素,直到重新满足规则。很明显,维护队列的时候要不断查询某一区间的最大值和最小值,这个可以用RMQ来解决。对于每个distance[i],最多进队列和出队列一次,所以总复杂度为O(nlogn+mn),这貌似有点大啊。
此题还必须有一个极端的优化(当时赛后才想到这个,悲剧。):由于维护队列的时候要不断查询某一区间的最大值和最小值,而log函数慢的一比,所以,要预处理log数组。
#include#include #include #include #include #include #include #include
法二:两个单调队列(一个维护最大,一个维护最小)
#include#include #include #include #include #include #include #include