这是一道好题。
首先对于 $x_i=y_i$ 的部分,这是一个经典的点分治问题,可以直接用点分治解决。
对于 $x_i\ne y_i$ 的部分,假设 $x_i$ 为 $y_i$ 祖先,可以把符合条件的点分为 $x_i$ 子树外的和 $x_i$ 子树内的。
令 $f_{i,j}$ 表示子树 $i$ 内距离 $i$ 不超过 $j$ 的节点个数,前者可以通过点分治和 $f_{x_i,d}$ 作差求得。
对于后者,首先链上的点一定符合条件,其次考虑枚举链上某个点 $u$,并枚举 $u$ 的一个不在链上的儿子 $v$,加上 $f_{v,d-1}$。即为答案。
对于 $x_i$ 不为 $y_i$ 祖先的情况,考虑先求出 LCA 然后拆成两条竖直的链来做。综上,现在有了一个不知道什么复杂度的暴力做法了,考虑优化。
注意到:对于链上的 $u$ 以及想要计算的 $v$,绝大部分 $v$ 是 $u$ 的轻儿子。换句话说,对树进行轻重链剖分,则一条路径上只有 $\log n$ 条轻边。
考虑设 $g_{i,j}$ 表示 $i$ 的所有轻儿子子树中,距离 $i$ 不超过 $j$ 的节点个数,先求出竖直链上的 $g_{u,d}$ 之和,对于一条位于查询路径上的轻边 $(u,v)$,其中 $u$ 为 $v$ 的父亲,只需要减去 $f_{v,d-1}$ 然后加上 $f_{son(u),d-1}$ 即可正确处理这条轻边的贡献。
链上的 $g_{i,j}$ 之和可以通过树上差分求出,令 $G_{i,j}$ 表示 $1\to i$ 路径上所有点 $u$ 的 $g_{u,j}$ 之和。
现在我们要做的是:
1. $O(n)$ 次查询距离点 $x$ 不超过 $k$ 的点的个数。
2. $O(n\log n)$ 次查询 $x$ 子树内距离点 $x$ 不超过 $k$ 的点个数。
3. $O(n)$ 次查询 $G_{i,j}$。
第一个可以点分治做到 $O(n\log^2 n)$,第二个可以用 dfs 序转化为二维数点做到 $O(n\log^2 n)$,第三者可以先离线询问,dfs 时暴力遍历轻子树做到 $O(n\log^2 n)$,所以整个题就可以做到 $O(n\log^2 n)$。
因为本题的边边权均为 $1$,可以做到 $O(n\log n)$ 完成第 $1,3$ 个部分(具体的,我们直接维护前缀和,加入一个子树可以用 $O(siz)$ 的复杂度求出对前缀和数组 $O(siz)$ 个位置的影响),第二个部分使用长链剖分应该也能做到 $O(n\log n)$。所以本题应该是可以 $O(n\log n) $ 的。
当然我比较懒,所以只实现了 $O(n\log^2 n)$ 的,不过感觉 1log 可能也挺好写的?