No.794 チーム戦

概要

N 人(偶数)の人がいて、i 番目の人は整数 A_i を持っている。これらの人々を使ってペアを N / 2 組作りたい。ただし、各ペア(i, j)について A_i + A_j <= K が成り立っていないといけない。

そのようなペアの分け方は全部で何通りあるか?

制約

  •  2 \le N \le 2 \cdot 10^5,  Nは偶数
  •  1 \le K \le 2 \cdot 10^9
  •  1\le A_i \le 10^9

考察

まず人の順番は無視していいので、A_iは昇順にソートしておくことにする。すなわちA_1 \le A_2 \le \dots \le A_Nが成り立っているものとする。

「2人の和がK以下」という制約が無ければ簡単で、答えは

 \binom{N}{2} \cdot \binom{N-2}{2}  \dots  \binom{2}{2} / (N / 2)!

となる。最後に(N / 2)!で割らなければいけないことに注意する。なぜなら、例えば[1,2,3,4,5,6]とあるとき、({1,2}, {3,4}, {5,6}), ({1,2}, {5,6}, {3,4}), ({3,4}, {1,2}, {5,6})...のように同じ分け方でも順序が違うものを重複して数えてしまうからだ。

上の考察は無駄ではなくてKが十分大きいときはこの答えがそのまま使える。より厳密に言うと、 A_{N-1} + A_{N} \le Kであるとき上の答えに帰着される。

こういうのは相方の候補数が少ないもの、つまりA_iが大きい順に考えてその候補数を掛け算していけばよさそうな感じがする。A_iの相方の集合よりA_{i-1}の相方の集合のほうが大きいので、A_iがどれを相方にしても、A_{i-1}の相方候補は1つ減るだけだから。(これを逆順にやってしまうとややこしくなってしまう……ということをABC114-Dで学んだ)

そうやりたいんだけど、問題はA_iA_{i-1}をペアにした場合とかを考えると、次にA_{i-1}を考えるのではなくA_{i-2}を考えなければいけない、みたいになってかなりややこしくなってしまう。どうすればいいんだろう……?

よく考えると A_iA_{i-1}とペアになれるっていうことは、 A_i + A_{i-1} \le Kが成り立っているということで、これは上の「制約が無いパターン」に帰着されていることが分かる。すなわち、 A_i + A_{i-1} \le Kが成り立っているときは、前のi人は自由にペアを組めるのだ。

なので、 A_i + A_{i - 1} \le Kがどこまで成り立つか?でグループ分けすると考えやすくなるのではないか、という考えが浮かぶ。すなわち A_i + A_{i - 1} \le Kを満たす最大の iをmとして、前半組m人、後半組N - m人と分けてみよう。すると前半組のm人はどの2人を選んでもペアに出来るし、後半組のN-m人はどの2人を選んでも絶対にペアに出来ないことが分かる。ということは後半組は相方を前半組から取ってこなければいけない、ということも分かる。

ここまで来ると最初の懸念であった「A_iA_{i-1}をペアにした場合とかを考えるとめんどくさい」という問題も解消されることが分かる。なぜなら後半組は絶対に前半組から相方を取ってくるので、後半組同士でペアになることは一切考えなくていいからだ。

これをアルゴリズムとして落とし込むと以下のようになる。

  1. ans = 1 とする
  2. 後半組の大きい順に、( K - A_i以下を満たす人の数) - (既に処理した後半組の人の数) をansにかけていく
  3. 後半組が全て処理できたら、前半組で残ったm - (N - m) = 2m - N人は自由にペアに出来るので制約条件の無い問題に帰着して、それをansにかける

実際はans = 0になる場合とかがあるのでその場合は少し修正しなければいけないけど、だいたいこんな感じ

感想

解説と少し違ったやり方で解いたので書きましたが、kmjpさんのやり方とほぼ一緒ですね。少し違うのはkmjpさんは A_i \le K / 2でグループ分けしてますね。確かにそっちのほうがシンプルだなあと思いました。