AtCoder Regular Contest 140 D問題メモ
D - One to One
問題文
- 全ての要素が 11 以上 NN 以下である長さ NN の整数列 X=(X1,X2,…,XN)X=(X1,X2,…,XN) に対して次の問題を考え、その答えを f(X)f(X) とします。
- NN 頂点の無向グラフ GG があります。(GG は多重辺や自己ループを含むことがあります。)
- GG の辺は NN 本あり、そのうち ii 番目の辺は頂点 ii と頂点 XiXi を繋ぐ辺です。
- GG の連結成分の個数を求めてください。
- 長さ NN の整数列 A=(A1,A2,…,AN)A=(A1,A2,…,AN) が与えられます。各 AiAi は 11 以上 NN 以下の整数あるいは −1−1 です。
- 全ての要素が 11 以上 NN 以下である長さ NN の整数列 X=(X1,X2,…,XN)X=(X1,X2,…,XN) であって、Ai≠−1⇒Ai=XiAi≠−1⇒Ai=Xi を満たすものを考えます。そのような全ての XX に対する f(X)f(X) の総和を 998244353998244353 で割ったあまりを求めてください。
制約
- 1≤N≤20001≤N≤2000
- AiAi は 11 以上 NN 以下あるいは −1−1 である。
解法
無向Functional Graphなので、各連結成分は1つだけ閉路を持つ。
逆に言うと「閉路の個数=連結成分の個数」なので閉路を数えることとしてよい。この問題はその方が考えやすい。
まず、-1 以外の辺をUnionFind等で結合する。(ここでの暫定的な連結成分を、“準連結成分”と呼ぶことにする)
各準連結成分は「①:-1の頂点を含まない、閉路を1つ含む準連結成分(俗称なもりグラフ)」と
「②:-1を1つだけ含む、木状の準連結成分」に分類される。
①の個数を XX、②の個数を YY として、②をつなぎに行く先で NYNY 通りのパターンがある。
①同士はどうやっても最終的に同じ連結成分になることはないので、X×NYX×NY 個はもう確定している。
②同士のみをつないだ連結成分が追加で何個できますか、という問題となる。
「1個できるのが○パターン、2個できるのが○パターン、、、」を求めるのは難しいので、主客転倒する。
「閉路を構成するような準連結成分の組」を1つ固定し、それが何個のパターンで計上されるかを、全ての組について足し合わせる。
ここで、②のみからなる「連結成分を構成する準連結成分の組」を固定しても、その個数をうまく計算するのは難しい。
②のみからなる「閉路を構成する組」を固定すると、計算しやすくなる。
後からその閉路に他の②がつなぎに来てもよいが、それは固定の対象としない。
②の準連結成分に順番を付け、頂点数をそれぞれ B1,B2,...,BYB1,B2,...,BY とする。
また、閉路を構成する組 I=(i1,i2,...,ik) を1つ固定する。
- ⅰ) どの順番でつなぐか: (k−1)!
- ⅱ) どの頂点につなぐか: ∏i∈IBi
- ⅲ) その他の頂点の決め方: どこにつないでもよい。NY−k
これらをかけあわせた結果が I に対する答えで、考えられる全ての I について総和を取ると全体の答えとなる。
ここで、ⅰとⅲはサイズ k にしか依存しないので、これを基準にまとめることを考えると、
- ∑{I∣|I|=k}∏i∈IBi
ⅱの総和を k ごとにまとめて計算できればよい。
で、これはDPで O(N2) だったり、畳み込みを使って O(Nlog2N) などで求められる。

