ntk log ntk

競プロや非競技プロのやったことを書いています.

ABC173 F - Intervals on Tree

F - Intervals on Tree

解法

コンテスト中にここまで気づけるようになりたい(この回はEで苦戦してFを見ていませんが…).

与えられるのは木であり,閉路が存在しない. よって,辺がない状態から辺を1つ増やすと,連結成分が必ず1つ減ることがわかる.

まったく辺がないときの連結成分の個数の合計は,

\displaystyle{\sum_{L=1}^N \sum_{R=L}^N (R-L+1) = \frac{1}{6}n(n^2 + 3n + 2)}

です.左辺から右辺を出すのに,wolframalphaの力を借りました.

上を計算したら,各辺が含まれる回数をそれぞれ引いてあげれば答えです.  1 \le L \le u_i \lt v_i \le R \le Nである各辺(u_i, v_i)について,u_iは,1からu_iまでLが取れます.そしてv_iは,v_iからNまでRが取れるので, 各辺が含まれる回数はそれぞれu_i \times (N - v_i + 1)です.

提出コード

def main():
    N = int(input())
    ans = N*(N**2 + 3*N + 2)//6
    for _ in range(N-1):
        a, b = (int(i) for i in input().split())
        if a > b:
            a, b = b, a
        ans -= a*(N-b+1)
    print(ans)


if __name__ == '__main__':
    main()

コンテスト終了直後のTLを見て,解法を理解しました.特にしゅんしゅんさんありがとうございます. ちなみにTwitterでコンテスト終了直後のTLを後から見たいときは, "filter:follows since:2020-07-05_22:40:00_JST until:2020-07-05_22:45:00_JST F問題"などと検索をかけるといいです.

自力ではサンプルとして,

5
1 2
1 3
2 4
2 5

を実験し,L=3のときの3 \le R \le 5を観察していて,ようやく\sum_{L=1}^N \sum_{R=L}^N (R-L+1)に気づけました.そのあと辺の数を引けばいいのはわかりましたが,上手く計算できず….

入力サイズからO(N2)が間に合わないので,f(L,R)を愚直に計算することはないな~とは最初に思っていましたが,ここまでスッキリとした解法だとは思いませんでした.木ゆえに閉路はないという性質が効いてるのが好きです.うーん、やっぱりコンテスト中に解きたかった(E問題さん…). f:id:ntk_ta01:20200707180505p:plain