某一天,我在思考有没有一种树上数据结构问题需要用 bfs 而非 dfs 序维护,然后诞生了这道题。
对于每个修改操作,我们要修改所有的 v 满足
dis(u,v)=dep(u)+dep(v)−2dep(LCA(u,v))≤k
于是考虑枚举 dep(v),此时有
dep(LCA(u,v))≥2dep(u)+dep(v)−k
即
dep(LCA(u,v))≥⌈2dep(u)+dep(v)−k⌉
我们设 u 的深度为 ⌈(dep(u)+dep(v)−k)/2⌉ 的祖先为 r,则 r 一定是 LCA(u,v) 的祖先。
于是我们知道,此时 v 一定是 r 的深度为 dep(v) 的子孙。
从下往上推一遍,即可知所有的 r 的深度为 dep(v) 的子孙都符合条件。
我们考虑在 bfs 序上面建立一棵线段树,这样一棵子树下所有深度相同的节点都是连续的。
只需 dfs 一次,预处理出每个结点对应深度的子孙落在哪一段即可。
注:为了存数组方便,数组中的下标是子孙与该结点的相对深度。
预处理复杂度 O(nk),单次修改复杂度 O(klogn),总时间复杂度为 O(nk+qklogn)。
Code