题意:给一棵树,然后问\(q\)个询问,每个是问和\(u\)这个节点共同拥有一个\(p\)倍祖先的点的个数。
思路:首先转化题意,就变成了问某个节点\(v\)所挂子树中有多少个节点深度为\(p+dep_v\)。
那么我们有三种方法来处理这个东西。
因为我们知道同一个子树中的节点的访问时间戳在一个区间内。
于是乎就可以把所有的深度的节点分别放在一个个vector中。
下面就可以直接二分出每一个询问的子树区间中多少个同一深度的节点了。dreamoon的离线方法。
其实差不多,就是他把所有的子树区间看做两个端点,用差分的思想扫一遍把前缀和乘上权加起来作为答案。
被我一写怎么看怎么像扫描线。。。shik的启发式合并方法。
这个就比较直接了,是从下往上,把所有的子树中的高度为几的有多少个合并起来,跑到一个节点就把以这个节点为根的所有询问的答案给记录下来。
其中,第一个方法是在线的,而且跑得快。
另外两个方法各有优秀之处。
(吐槽dreamoon的码风