解説


この問題は各頂点を根とした根付き木それぞれについて、累積 を持ちながら DFS をすることで全体で で解くことができます( とします)。計算量解析の詳細は後述します。なお、この問題は HL 分解でも解くことができます。

まずは愚直解をベースに考察をしてみましょう。頂点の組 を指定して、頂点 から頂点 への最短パス を求めることができれば、頂点の組 を全探索することで答えを計算することができます。

  • 最短パス が効率良く求まったと仮定して、答えを求めるパートの計算量はどうなるでしょうか? 最短パス の頂点数を とおき、 の計算量が最悪ケースで になることに注意すれば、求める計算量は になります。最悪ケースとして木がパスグラフである場合を考えると となるため(導出は読者への課題とします)、愚直解では間に合わないことが分かります。

  • 最短パス はどのように求めたらいいでしょうか? 頂点の組 ごとに DFS で愚直に計算することはできますが、これでは計算量が最悪ケースで になり、全体では前述のパスグラフの場合で最悪 の計算量となるため間に合いません。適当に根を決めて根からのパスを DFS で前計算しておき LCA を用いて効率よく構築することは可能ですが、パスグラフの場合に「パスに登場する頂点数」の総和のオーダーが になってしまうため間に合いません。

これらのことを踏まえると、頂点の組 を指定して最短パス を毎回独立に求める方法にはかなりの無駄が生じていることが分かります(それぞれのパスには共通部分が数多く存在しているためです)。よって、その共通部分を使い回すことで効率よく計算できないかを考えることが本問の重要なポイントになります。

やや天下り的ですが、これには DFS がぴったりハマります。頂点 を根とする根付き木を DFS することを考えると、 であるような頂点の組 の最短パス で全て列挙することができます。 についても DFS をしながら累積計算をすることで効率よく求められます。

ところで、制約を確認してみると となっていることから、 の計算パートはパスごとに最悪 の計算量がかかるとして見積もれば、「頂点 を根とする根付き木の DFS」を について全探索することで全体で で解くことができます。

計算量解析


一般に、最大公約数 はユークリッドの互除法によって で計算できます(最悪ケースは がフィボナッチ数列の隣接 項であるとき)。では 個の整数 の最大公約数の計算量はどうなるでしょうか? 愚直に見積もれば となりますが( とします)、ユークリッドの互除法の計算ステップ回数をよく考えると に抑えられることが分かります。

本問の場合、各頂点を根とした根付き木それぞれについて、DFS をしながら累積的に を計算するため、全体計算量の上界を適切に解析することは難しくなります。しかし、定数倍 は付くものの のテストケースは下記のように構築することができます。

  • スターグラフを作り、 個の葉を半数ずつのグループ A, B に分ける
  • フィボナッチ数列の隣接 項であって 程度のものを選ぶ
    • など
  • 隣接 項の一方をグループ A の葉に、もう一方をグループ B の葉にそれぞれ配置する
  • 中央ノードに隣接 項の最小公倍数を配置する
    • 例えば、
  • 以上により、 の計算ステップ回数が 程度となるパスが、グループ A の葉とグループ B の葉のペアの個数()の分だけ存在するため、全体では の計算量となるテストケースを構築することができます。

のテストケースの構築に関する具体案及びその計算量解析は tester の MMNMM さんの指摘によるものです。ありがとうございます。

解答例


解答例(C++)
解答例(Python)