問題
$ N $ 個の整数があります。
整数は小さい順に $ A_1,A_2,…,A_N $ と並んでいます。
異なる2つの整数のペアを選ぶ方法は全部で $ N(N-1)/2 $ 通りありますが、その中で差が $ K $ 以下であるような選び方は何通りあるでしょうか。
[制約]
🔹$ 1 \leqq N \leqq 100000 $
🔹$ 1 \leqq K \leqq 10^9 $
🔹$ 1 \leqq A_1 < A_2 < … < A_N \leqq 10^9 $
解き方・ソースコード
$ A_t \leqq A_i + K $ を満たす最大の $ t $ を $ R_i $ とし、$ R_i $ の値を次のように計算します。
🔹手順1 $ i = 1 $ であれば $ R_i = 1 $ から、そうでなければ $ R_i = R_{i-1} $ からスタートする。
🔹手順2 差分 $ A_{R_{i}} - A_i $ が $ K $ を超えないギリギリまで、$ R_i $ を1増やす操作を繰り返す。
求めるペアの個数は $ (R_i - i) $ 通りで、答えは次式で計算できます。
$$ (R_1 - 1) + (R_2 - 2) + … + (R_{N-1} - (N -1)) $$
[Google Colaboratory]
1 | #--------- 入力例 ----------- |
このアルゴリズムは、しゃくとり虫の動きにたとえてしゃくとり法と呼ばれています。
$ R_i $ を増やす操作は合計 $ N - 1 $ しか行われないので、計算量は $ O(N) $ となります。
[実行結果]
[2, None, None, None, None, None, None] [2, 3, None, None, None, None, None] [2, 3, 3, None, None, None, None] [2, 3, 3, 6, None, None, None] [2, 3, 3, 6, 6, None, None] [2, 3, 3, 6, 6, 6, None] 解: 11
整数のペアの差が10以下になる組み合わせは、11通りあることを導き出すことができました。