算是一个套路题吧
我一开始考虑的时候,想了一个 \(O(n\sqrt n\log n)\) 的做法,但是通过调整块长好像可以做到 \(O(n\sqrt {n\log n})\)
大概思路就是考虑根号分治。对于每一次修改来说,如果儿子的个数小于 B 个,直接考虑对每个儿子树剖修改一下就行,而对于大于 B 个儿子的点,直接考虑记录一下这个点及其贡献。
对于一次询问,首先线段树中查询自己的权值。然后考虑这个点的所有祖先计算它们对自己的贡献,其中第二类点个数只有 \(O(\frac{n}{B})\) 个
我们不用 树剖维护这棵树,而是采用分块维护。做到 \(O(1)\) 区间修改,\(O(\sqrt n)\)单点 查询
复杂度可以降到 \(O(n\sqrt n)\)
我们考虑一个比较神仙的做法,每次修改的时候,对外子树以及重儿子做一个树剖加法。
每次询问的时候线段树中查询答案,并在树剖跳到根节点的链,对于相邻两条链的时候,计算一下贡献即可。
这个思路还是有点意思的,非常清奇。