毎日格上の問題を倒すやつの47日目です。
もとい、FPSウィークの2日目です。飽きたら終わります。*1
問題リンク
問題概要
個の部品があって、 番目の部品には 個の穴があるよ。これらの穴は区別できるよ。
また、 個の接続用部品があるよ。
これらを連結になるようにつなげる通り数を で割ったあまりを求めてね。
解法
まずは、次数制限つきケイリーの定理を考えます。
これは頂点 の次数が である 頂点のラベル付き木*2の個数が であるというものです。*3
また、部品 に刺す部品の個数が のとき、通り数は です。
なので、答えは
となります。
とりあえず は最後に掛けることにすると、答えは
となります。
ここで、それぞれの項を見てみましょう。 はほぼ二項係数です。もっと言うと、これは です。
すると、さらに
と変形できます。
左はめちゃくちゃ簡単なので、右の二項係数たちを考えます。すると、それぞれは二項定理を取り出して と表せます。
また、この総和は明らかに畳み込みです。そのため、さらに
と変形できます。この右にも二項定理を適用できるので、最終的には
となります。このまま計算することも可能ですが、
と解釈すれば
とできて、もう掛け算をやるだけです。
提出コード
MOD=998244353 N=int(input()) d=list(map(int,input().split())) top=1 for i in range(N-2): top*=(i+1) top%=MOD mul=1 for i in d: mul*=i mul%=MOD comb=1 n=sum(d)-N for i in range(N-2): comb*=(n-i) comb%=MOD print(comb*mul%MOD)
Submission #47320328 - AtCoder Regular Contest 106
感想
二項定理ってだいぶ優秀よね…
Prüferコードを知った段階ではすごく苦戦したけど今となってはさらっと解けていいなぁ
*1:【今日の精進】AISING2020F - Two Snuke - halcの競プロ精進ブログも見てほしいな…
*2:ただし、 の総和は です