「UR#2」树上 GCD

题目链接

讲的是一个较劣的做法。

先转换成求 \(\gcd\)\(d\) 倍数的种数。考虑无脑上根号分治。设阈值为 \(B\),我们对不超过 \(B\)\(d\) 暴力求。怎么求呢?我们有一个十分巧妙的方法,记录每个点子树与它距离为 \(d\) 的倍数的节点数,这样直接树上乱做一下就可以了,答案也是非常容易求的。这部分的时间复杂度是 \(\mathcal O(nB)\)。再考虑超过 \(B\)\(d\),我们可以直接考虑保存下来每一个节点所对应子树的所有点的深度。这可以方便地使用启发式合并求出。考虑怎么算答案,发现就是两个集合合并时进行计算。然后是 \(\mathcal O(n^2\log n)\) 的智障做法。但是考虑当两个集合都大于 \(B\) 时才有贡献。这时只会计算 \(\mathcal O(\dfrac{n}{B})\) 次。总复杂度 \(\mathcal O(nB+\dfrac{n^2}{B}\log n)\)。取 \(B=\sqrt{n\log n}\) 时复杂度最优,为 \(\mathcal O(n\sqrt{n\log n})\)

总结,这种题就是,你很难感觉他是根号分治,但是知道根号分治后又觉得很自然。还是练少了导致的。

posted @ 2024-02-07 21:21  TulipeNoire  阅读(7)  评论(1编辑  收藏  举报