問題出在codechef中的travtree問題。在editorial,他們建議通過記錄每個節點在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
之間的路徑無關的節點!