ARC138A - Larger Score

解法1

考え方

$S_{1} = [A_{1},...,A_{K}]$と$S_{2} = [A_{K + 1},...,A_{N}]$の中から1つずつ$A_{i} < A_{j}$となるようなものを選んで,$A_{j}$を$K$番目に,$A_{i}$を$K + 1$番目に持ってくればスコアを$s+1$以上にできる.操作回数は,$A_{i}$を$K - 1$番目に持ってきて,$A_{j}$を$K$番目に持ってきて,その後$A_{i}$と$A_{j}$を入れ替えるから$(K - 1 - i) + (j - K) + 1 = j - i$回.このような$(i,j)$の集合のうち$j - i$が最も小さくなるものを入れ替える操作回数が答え.

$S_{2}$を前から見ていって,$A_{i - 1} > A_{i}$となる$i$があれば,$A_{i}$を$A_{i - 1}$で置き換える.こうしてできた配列を$S_{2}^{\prime}$とする($S_{2}$を単調増加になるように修正).

$S_{1}$を前から見ていって,$A_{i}$を$S_{2}^{\prime}$にbisect_rightすれば,$A_{i} < A_{K + j}$($A_{i} \in S_{1}, A_{K + j} \in S_{2}$)となる最小のindex $j(i)$を求めることができる.

答えは$\displaystyle \min_{1 \leq i \leq K} j (i)$となる.

回答例

from bisect import bisect_right

N, K = map(int, input().split())
A = list(map(int, input().split()))

S1 = A[:K]
S2 = [A[K]]
for x in A[K + 1:]:
    S2.append(max(S2[-1], x))

ans = 1 << 60
for i, x in enumerate(S1):
    j = bisect_right(S2, x)
    if j < len(S2):
        ans = min(ans, K + j - i)

print(ans if ans < 1<<60 else -1)

【参考】Submission #30813624 - Daiwa Securities Co. Ltd. Programming Contest 2022 Spring(AtCoder Regular Contest 138)