Official

E - Peak Editorial by physics0523


半開区間という少し見慣れない用語が出てきたので、問題文の詳細な説明を利用しながら状況を整理しましょう。以下の \(2\) 通りの場合について議論します。
なお、プレゼントは必ず整数座標に置かれていることに注意してください。

  • 選んだ実数 \(x\) が整数である場合
    • 座標 \(x,x+1,\dots,x+M-1\) にあるプレゼントを獲得できます。座標 \(x+M\) にあるプレゼントは獲得できないことに注意してください。
  • 選んだ実数 \(x\) が整数でない場合
    • \(x\) を切り上げた整数を \(\lceil x \rceil\) とします。このとき、座標 \(\lceil x \rceil, \lceil x \rceil+1,\dots,\lceil x \rceil+M-1\) にあるプレゼントを獲得できます。

どちらの場合でも、結局は「連続する整数座標を \(M\) 個選び、それらに置かれているプレゼントを全て獲得する」ことになると分かります。

すると、 \(A_i\) を予めソートし、取るプレゼントのうち最も小さい座標にあるものを固定した上で取ることのできるプレゼントのうち最も大きい座標にあるものを求めていけばよいです。
これは、尺取り法や二分探索などで時間計算量 \(O(N)\)\(O(N \log N)\) といった計算量で解くことができます。 ( ソートによる時間計算量 \(O(N \log N)\) が別個に発生することに留意してください )

実装例 (Python):

n,m = map(int,input().split())
a = list(map(int,input().split()))

a.sort()
a.append(9000000000000)

res = 0
r = 0
for l in range(0,n):
    while a[r] < a[l]+m:
        r += 1
    res = max(res,r-l)

print(res)

posted:
last update: