【题解】CF246E Blood Cousins Return(树上查询K-Son)

题意

给定一片 \(n\) 个点的森林,每个节点有一个名字。

\(m\) 次询问,每次询问一个节点的 \(K-Son\) 共有个多少不同的名字。一个节点的 \(K-Son\) 即为在该节点子树内的,深度是该节点深度 \(+K\) 的节点。

\(n,m\le 10^5\)

我的沙笔莫队做法

找到一个点 \(x\)\(K-Son\),相当于找到深度为 \(dep[x]+K\) 且在 \(x\) 子树中的点。

\(x\) 的子树中可以用 \(dfn\) 序进行限定。因此我们现在有 \(2\) 个限制:\(dep\)\(dfn\)

考虑将所有深度一样的点放入一个 \(vector\),并将所有 \(vector\) 按照 \(dfn\) 从小到大排序。则任意一个点的所有 \(K-Son\) 在某个 \(vector\) (其对应深度为 \(dep[x]+K\))中的连续一段。

问题就变成了,给定 \(m\) 个询问,每次询问一个深度中,其 \(vector\) 的连续一段中有多少不同的名字。

注意到如果只有一个深度,那我们就可以用莫队摆平它。现在有至多 \(n\) 个深度,所以我们对所有深度都做一遍莫队即可。

\(vec[d]\) 为存储深度为 \(d\) 的点的 \(vector\),它的大小为 \(siz_i\)。块长取 \(\sqrt{\max siz_i}\) 可以通过,时间复杂度为 \(O(\sum\limits_{i} siz_i\sqrt{siz_i})\)

也许可以卡?但是应该不好卡,我没卡掉。而且实测只跑了530 ms,现在是Rank 6。

细节有点多,主要是在处理莫队指针移动的地方。

提交记录:https://codeforces.com/contest/246/submission/163660600

posted @ 2022-07-11 19:59  hzy1  阅读(160)  评论(1编辑  收藏  举报