这个问题是由 codechef 中的travtree问题引起的。在社论DFS
中,他们建议通过在遍历中记录每个节点的发现和退出时间,将树线性化为数组。现在我们可以通过汇总该节点sum subtree
段中发生的事件来快速回答有关- 的查询。[discovery time, exit time]
(我们使用Fenwick
树来快速回答这些查询)。
然而,为了解决这个问题,我们还需要快速回答sum path
查询。也就是对沿最短路径发生的事件求和a, b
。这怎么可能?他们给出的答案是这样的:
对于每个有趣的事件,他们都会更新:
update(BT2,event_node,1);
update(BT2,out[event_node],-1);
现在sum path(a,b)
是这样的:
int l = lca(a,b);
ans = query(BT2,a) + query(BT2,b) - query(BT2,l) - (l==1 ? 0 : query(BT2, parent[0][l]));
query
前缀总和在哪里。怎么正确??当您查看前缀总和时,您可能会遇到许多与和a
之间的路径无关的节点!l
a