UNIQUE VISION Programming Contest 2024 Summer (AtCoder Beginner Contest 359) G問題メモ

G - Sum of Tree Distance

G - Sum of Tree Distance

いろんな解法がある。

問題

  • $N$ 頂点の木があり、頂点 $v$ には色 $A_v$ が塗られている
  • $d(u,v)$ を以下で定義する
    • $u$ と $v$ が同じ色で塗られている($A_u=A_v$)とき、$u$ と $v$ の距離
    • $u$ と $v$ が異なる色で塗られている($A_u \neq A_v$)とき、$0$
  • $\displaystyle \sum_{u=1}^{N-1} \sum_{v=u+1}^{N} d(u,v)$ を求めよ
  • $2 \le N \le 2 \times 10^5$

解法1 - 平方根で場合分け

同じ色の頂点が何個あるかで色分けする。
閾値 $B$ を決める。

$B$ 個未満の色

同じ色が $B$ 個未満の場合、愚直に全ペアの距離を1つ1つ求める。
オイラーツアー+区間最小値が取得できるSparseTable を前計算しておくことにより、2頂点間の距離は $O(1)$ で求められる。
(言語によってはbit_lengthを求める際に軽い $O(\log{N})$ がかかるが)

1つの色につき最大 $O(B^2)$、全体では $O(B^2 \dfrac{N}{B})$ かかる。
区間最小値をセグ木でやるとlogがつき、若干TLEが厳しくなる。

$B$ 個以上の色

同じ色が $B$ 個以上の頂点は、木DPする。

  • $\mathrm{DP}_a[v]=v$ 以下の、全ての色 $a$ の頂点の(個数, $v$ までの距離の和)

1つの色につき $O(N)$、全体では $O(N \dfrac{N}{B})$ かかる。


この2つのバランスが取れるのは、$B = \sqrt{N}$ の時で、全体 $O(N \sqrt{N})$ となる。

PyPyだと数個のテストケースでTLEが取れなかった。
Numbaに書き直すと余裕を持って通った。(約2000ms)

Python3

解法2 - 木DP+マージテク

距離計算の部分にちょっとした工夫が必要になるが、こちらの方が実装量は少ない。
ただ、ライングラフ+色の種類が多いテストケースに対して $O(N^2)$ の空間計算量が必要になるのでMLEの危険性がある? (まぁ、定数倍が大きいわけではないし、MLEの制限はTLEと比べると緩いので大丈夫か)

1回の木DPで、全ての色について求める。

  • $\mathrm{DP}[v,a]=$ 頂点 $v$ 以下の部分木で、色 $a$ の全ての頂点の(個数, 深さの総和)

例えば解法1のDPでは「頂点 $v$ までの距離の総和」を値として持ったため、頂点を遡る毎に更新が必要になった。
しかし、マージテクをする場合は、小さい方を大きい方にマージする分、大きい方は更新が発生してはいけない。

「深さ」を値として持つことで、距離を求めることを可能にしつつ、更新が発生しないようにできる。
「子孫 $u$ から祖先 $v$ までの距離」=「$u$ の深さ - $v$ の深さ」

これで、$a$ の種類数が少ない方を多い方にマージしていくことで、時間計算量は $O(N \log{N})$ となる。
DPの値は、配列で持つと明確に $O(N^2)$ の空間を要するため、基本的には辞書で持つことになる。これに log がかかる言語では、$O(N \log^2{N})$ となる。

Python

その他の解法

  • 重心分解
  • Auxiliary Tree
programming_algorithm/contest_history/atcoder/2024/0622_abc359.txt · 最終更新: 2024/06/25 by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0