E - Exactly K Triangles Editorial by NatsubiSogan


「公式解説」とありますが、ユーザー解説のような立ち位置の解説となっております。本解説の行間を埋める手助けになれば幸いです。

辺の長さが \(a,b,c \ (a<b<c)\) の三角形が存在することは、\(a+b>c\) が成り立つことと同値です。以下ではこれを既知とします。

上の事実より、数列は値の降順に生成することとします。

\(\displaystyle\binom{m}{3}\)\(K\) を超えない最大の \(m\) をとり、暫定的に \(A^{\prime}=\overbrace{(10^{18},10^{18},\cdots,10^{18})}^{m \text{個}}\) とします。この時点で条件を満たしているとき(\(\displaystyle\binom{m}{3} = K\) のとき)はこれをそのまま答えとして出力します。

そうでない時は、\(A\) の末尾にもう \(1\) つ要素を追加することで辻褄を合わせたいですが、このままではうまくいきません。

以下の条件を満たす数列 \(B=(B_1,B_2,\cdots,B_m)\) を作りましょう:

  • 全てのペアの差が distinct である。つまり、どのように \(4\) 整数 \(i_1, j_1, i_2, j_2 \ (1 \leq i_1 < j_1 \leq m, 1 \leq i_2 < j_2 \leq m, (i_1,j_1) \neq (i_2,j_2))\) を取っても、\(|B_{i_1} - B_{j_1}| \neq |B_{i_2} - B_{j_2}|\) が成り立つ。

このような数列のうち辞書順で最小のものを現実的な時間で求めるのは困難であると思われますが(詳細は確かめていません)、原案者解は \(B_k = k^5\) とした数列が この制約下では 常に条件を満たすことを利用しています。他にも様々な構築方法が考えられると思います。乱択によっても現実的な時間で求めることが出来るようです。

さて、\(B\) が用意できたので、数列 \(A\) を以下のように変更しましょう。

  • \(i \ (1 \leq i \leq m)\) について、\(A_i = A^{\prime}_i - B_i\) とする。

このようにすることで、末尾に追加する要素の値が増えていくにつれて、三角形の数が \(1\) ずつ増えるようになります(つまり、飛び飛びの値を取ることがなくなります)。

末尾の要素があまりに大きくなりすぎると正確な値が得られないのではないかと思うかもしれませんが、この値を \(10^{15}\) より大きくする必要はないということがすぐに分かるので、その心配は無用です。

よって、最後の要素を二分探索で決め打つことで、どのような \(K\) に対しても条件を満たす数列を構築することが出来ました。

posted:
last update: