解法
まずは入力を各身長ごとの人数として集計します。 を身長が
である人の人数とします。
であり、
人であるような身長を無視すれば身長の種類数は
以下です。
条件を満たす組み方をDPなどで直接数えようとすると、 から落ちず厳しいです。
包除原理を適用します。同じ身長で組んでいるペアを「違反ペア」と呼ぶことにして、違反ペアを 個以上集めた集合を
とします。「
に含まれるペアは必ず組んであって、その他のペアは自由に組まれているような組み方の数」を
とすると、答えは包除原理から
と計算できます。集合 の取り方は膨大にあるので
のサイズごとに集計することにします。
まずはそれぞれの身長ごとに独立に、違反ペアをいくつか組む組み方を数えます。以下の値を計算します。
身長が
の人の中で、違反ペアをちょうど
組だけ組むような組み方。(それ以外の人の組み方はまだ決めない)
これはまず、違反ペアに参加する人を選ぶのが 通り。その中で違反ペアを組む組み方は、
- まず
人適当に誰かを選び、その人の相方を残りの
人の中から選ぶ。
- また
人適当に誰かを選び、その人の相方を残りの
人の中から選ぶ。
- …
と考えると、二重階乗を用いて 通りと計算できます。この
は
から
まで取り得ます。
各身長ごとに求めた数列 を全てマージします。身長
の人の違反ペアが
組、身長
の人の違反ペアが
組…という組み方を合わせると、合計違反ペアが
組であるような組み方が
通り得られます。これを全ての
について計算するので、これは数列をFFT(NTT)でマージすることに相当します。
これを最後までマージすると、以下の値を示す数列が得られます。
全ての人の中で、違反ペアをちょうど
組だけ組むような組み方。(それ以外の人の組み方はまだ決めない)
これに残りのペアの組み方 を掛けると、「
であるような
についての
の和」が得られます。これを包除原理の式に従い合計すると答えになります。
あとはNTTのマージにかかる計算量を落とす必要があります。各身長に対する の長さは
であり、
なので、全ての数列の長さの和は
以下です。
何も考えずにマージすると、長い数列に短い数列を何回もマージするような場合に最悪で の計算量が掛かってしまいます。
マージの順番を工夫して、以下の二分木のようにマージをするとどうでしょうか。

二分木の1段分のマージでは、長さの和が 以下である数列たちが1度ずつNTTでマージされるので、合計で計算量
になります。そして二分木のようにマージすると
段で全てマージし終わるので、全体計算量
でマージできます。
数列の本数が2冪でないときはトーナメントのシードのような扱いをします。また二分木でのマージとは挙動が少し異なりますが、数列たちをキューに入れて「先頭から 本取り出してマージした結果を末尾に入れる」という処理を
本になるまで繰り返しても同様の計算量が達成できます。