配列のなかから指定された値に対して K 番目に近い値を取得する方法を考えます。

D – K-th Nearest

D – K-th Nearest

数直線上に N + Q 個の点 A_1, … , A_N, B_1, …, B_Q があり、点 A_i の座標は a_i、点 B_j の座標は b_j です。

j = 1, 2, …, Q それぞれについて、以下の問題に答えてください。

点 A_1, A_2, …, A_N のうち点 B_j との距離が k_j 番目に近い点を X としたとき、点 X と点 B_j との距離を求めよ。

入力されるデータ

N Q
a_1 a_2 … a_N
b_1 k_1
b 2 k_2

b_Q k_Q

ただし、
1 ≦ N, Q ≦ 10^5
– 10^8 ≦ a_i, b_j ≦ 10^8
1 ≦ k_j ≦ N

これはある値が指定されたときに配列のなかからK 番目にその値に近い値を取得する問題とみることができます。最大で 10^5 回のクエリが飛んでくるので処理を高速化する方法を考えなければなりません。

二分探索法で探す

このような問題は二分探索が有効です。まず配列 A をソートしましょう。そして配列の要素のうち X – m 以上 X + m 以下の個数が K になる m の最小値を探します。

二分探索法で探すのでBinarySearchクラスを定義します。コンストラクタには配列 A を渡します。

前提として指定された要素以上の値が現れる最小のインデックスを取得するLowerBoundメソッド、指定された要素より大きい値が現れる最小のインデックスを取得するUpperBoundメソッド、指定された要素が存在するかを確認するExistメソッドをを定義します。

二分探索法で target に K 番目に近い値を取得します。

定義したクラスを用いて解を求めます。