問題はコーデックのtravtree問題によって動機付けられます。 editorialでは、各ノードの検出と終了時間をDFS
トラバーサルで記録することによって、ツリーを配列に線形化することを推奨しています。今すぐ、そのノードの[discovery time, exit time]
セグメントで発生したイベントを合計することで、sum subtree
に関する質問に素早く答えることができます。 (私たちはFenwick
ツリーを使ってこれらのクエリに素早く答える)。ツリーを配列に線形化し、パス上の "sum"クエリに応答する
この問題を解決するには、sum path
の質問にすばやく答える必要があります。つまり、a, b
の最短経路で発生したイベントを合計します。そんなことがあるものか?
update(BT2,event_node,1);
update(BT2,out[event_node],-1);
とsum path(a,b)
は今、このです:query
プレフィックス合計です
int l = lca(a,b);
ans = query(BT2,a) + query(BT2,b) - query(BT2,l) - (l==1 ? 0 : query(BT2, parent[0][l]));
。彼らはこれを更新するごとに興味深いイベントについて
:彼らは与える答えはこれですそれはどうやって正しいですか?接頭辞の和をa
まで見ると、l
とa
の間のパスとは無関係の多くのノードが発生する可能性があります。
イベントがノードv
に起こる、我々update(IN[v], 1)
とupdate(OUT[v], -1)
:私たちは確かに次の操作を実行する必要があるツリーノード間の最短経路a, b
に起こった出来事の合計 - sum path
クエリを線形化するために