好难(too hard)

link\color{deeppink}{link}

注意到对于一个点而言,每一个操作本质是将某个值复制到另外一个点上。

考虑点分治,每次求出值到分治中心的后的贡献,即求出点最早到分治中心的时间 tit_i,而后求出分治中心在 tit_i 之后到其他子树的贡献。

考虑将每一个操作转为一条边,而后求出每一条边多久可以做出贡献,即求出 timitim_i 表示 ii 操作最早连接到分治中心的时间,同时求出 fif_i 表示 ii 这个点的最早时间。timtim 可以用双指针来求,fxf_x 就是 faxxfa_x\rightarrow x 的最早的边的 timtim

考虑什么情况下 jj 会对 ii 产生贡献。

显然,分治中心到 jj 的第一级祖先 pp(即分治中心的儿子)的时间大于 fif_ipp 在这个时间之后还可以转移到 jj

考虑再来一遍 dfs,按照边的时间从大到小走(其实就是前向心),记录一个 curcur 为当前以及走到哪条边了以及 timetime 表示分治中心到 pp 的时间,然后从 curcur 开始走,走的边的时间需要是递增的,就可以求出最大的时间 gxg_x 了。

然后就是求出对于每一个 ii,大于等于 fif_igxg_x 个数,然后再容斥掉同一子树的贡献即可。

以上是最后询问每个点的方法,但是询问呢?

考虑分治时,对于每一个询问操作枚举一遍,然后在 ansians_i 里面加上/减去

 fu  gx  i  gx 大于等于~f_u~的~g_x~个数-大于等于~i~的~g_x~个数。当然,fu<if_u<i 的特判掉。

时间是 O(nlog2n)O(n\log^2n)。注意还要将询问操作搞到点上去,否则复杂度还要乘个 qq。常数有点大。