杂题乱做

给一棵有根树,求距离 \(x\to y\) 的链不大于 \(d\) 的点的个数。保证 \(x\)\(y\) 的祖先。

\(d\le n,q\le2e5\)

冷静分析一波,我们发现假如我们设 \(f_{u,d}\) 表示 \(u\) 子树内距离不超过 \(d\) 的点的个数,我们要算的就是 \(\sum_{u\in x\to y}f_{u,d}-f_{u,d-1}+f_{x,d-1}\)

这个东西很好看啊!我们现在只需要算 \(\sum_{u\in x\to y}f_{u,d}\) 了,也就是只需要算 \(\sum_{u\in 1\to y}f_{u,d}\)

这东西长得一脸二维偏序的样子啊!一开始我胡了一个线段树合并 + 历史和的神秘做法,不知道能不能写,但反正很难写。

我们这里考虑另一种式子的意义。把上面的式子写成 \(\sum_{u\in x\to y}f_{u,d}-f_{son,d-1}\),发现这个东西就是 \(u\) 的子树去掉一棵的这么一个东西啊!

轻重链剖分,把询问分到 \(O(\log n)\) 个链上。注意到轻儿子的大小总数是 \(O(n\log n)\) 的,我们考虑统计一个 \(g_{u,d}\) 表示 \(u\) 的轻儿子子树内距离不超过 \(d\) 的点的个数。这个可以暴力 gank 上去。

然后我们先做个重链上前缀和看看我们目前得到的东西跟我们想要的有多大区别。我们发现,在轻边处我们会多算一个轻儿子少算一个重儿子,但这只有 \(O(\log n)\) 个,我们特殊处理即可。

实际上写起来有一车要离线下来的询问,很难写,所以我没写。upd:写了。

注意到我们的询问少一些,修改多一些,好像有 \(O(n\log n)\) 算法?(Scaling?)

upd on 5.27:

注意到我们有 \(O(n\log n)\) 次询问 \(f_{u,d}\),考虑这个东西怎么 \(O(1)\) 做。发现 \(f_{u,d}=sz_u-\sum_vsz_v\),其中 \(v\) 是与 \(u\) 距离为 \(d+1\) 的点,这个可以采用离线 + 差分的方法做。

对于 \(\sum_ug_{u,d}\),我们使用类似的方法就可以了。

\(O(n\log n)\)

posted @ 2023-05-24 21:28  PYD1  阅读(26)  评论(0)    收藏  举报