如果可以接受离线解决方案,则两次深度优先搜索就可以完成这项工作。
假设我们可以索引所有从 0 到 n - 1的n
查询(node, p)
我们可以将每个查询(node, p)
转换为另一种类型的查询(ancestor , p)
,如下所示:
查询的答案(node, p)
,节点有级别a
(从根到此节点的距离是a
),是级别a
的祖先的后代级别的数量a - p
。因此,对于每个查询,我们都可以找到那个祖先是谁:
伪代码
dfs(int node, int level, int[]path, int[] ancestorForQuery, List<Query>[]data){
path[level] = node;
visit all child node;
for(Query query : data[node])
if(query.p <= level)
ancestorForQuery[query.index] = path[level - p];
}
现在,在第一个 DFS 之后,我们有一个新类型的查询,而不是原来的查询(ancestor, p)
假设我们有一个数组count
,它在 index 处i
存储了具有 level 的节点的数量i
。假设a
在 level的节点x
,我们需要计算p
后代的数量,所以,这个查询的结果是:
query result = count[x + p] after we visit a - count[x + p] before we visit a
伪代码
dfs2(int node, int level, int[] result, int[]count, List<TransformedQuery>[]data){
count[level] ++;
for(TransformedQuery query : data[node]){
result[query.index] -= count[level + query.p];
}
visit all child node;
for(TransformedQuery query : data[node]){
result[query.index] += count[level + query.p];
}
}
每个查询的结果存储在result
数组中。