题目大意:
给一棵树,n个节点,每条边有个权值,从每个点i出发有个不经过自己走过的点的最远距离Ma[i],有m个询问,每个询问有个q,求最大的连续节点区间长度ans,使得该区间内最大的M[i]和最小的M[j]之差不超过q。
解题思路一:
这套题目好卡时间。
树形dp+二分+单调队列,几个基本的知识点杂糅在一起。
先用树形dp求出从任意一点i出发的Ma[i].两遍dfs,第一遍求出每个节点为根到儿子方向的最大距离并记录最大距离得到的直接儿子,和与最大距离路径没有重边的次大距离。第二遍求出每个点的最远距离Ma[i]要么从儿子方向得到,要么从父亲方向得到。
然后对于每个询问q,二分区间长度mid,用单调队列求出区间长度为mid的最大Ma[i]和最小Ma[j]的差值的最小值pp。保存起来,当已经求得了该区间长度的值pp时,直接返回pp.
与q比较,因为是存在性问题,每次都把该区间长度的最小的值pp来比较。这样一区间长度为标准,避免了,每次查询相同区间长度只是q不同的情况。不然会超时。
代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
解题思路二:
求出Ma[i]数组后,可以用RMQ nlogn的时间复杂度来预处理所有区间的最大值和最小值。
然后对于每个询问q,用两个指针l,r.从前至后按以i开始能够达到最大的区间长度的顺序扫,不过当以i开始的最大的满足的区间长度为L时,向右移动l指针,此时r指针不必移动,因为现在只用考虑区间长度>=L的情况,这样就利用了只找可能满足的区间长度越来越大的情况的性质。这样每个位置最多进出一次,时间复杂度为o(N)。
所以总的时间复杂度为nlogn+m*n.
代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include