結果
問題 |
No.711 競技レーティング単調増加
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:07:16 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 149 ms / 2,000 ms |
コード長 | 4,799 bytes |
コンパイル時間 | 243 ms |
コンパイル使用メモリ | 82,668 KB |
実行使用メモリ | 119,384 KB |
最終ジャッジ日時 | 2025-05-14 13:08:54 |
合計ジャッジ時間 | 6,347 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 41 |
ソースコード
import sys import bisect # Function to read input efficiently readline = sys.stdin.readline def solve(): # Read N, the number of elements N = int(readline()) # Read the array A A = list(map(int, readline().split())) # The problem requires finding the minimum number of operations to make A strictly increasing. # An operation consists of changing an element A[i] to any positive integer. # This is equivalent to maximizing the number of elements we *don't* change. # Let the final strictly increasing array be B. # If we decide to keep A[i] (0-based index), meaning B[i] = A[i], then these kept elements must satisfy: # 1. If we keep A[i] and A[j] with i < j, then B[i] < B[j]. So A[i] < A[j]. # 2. The sequence B must be strictly increasing: B[0] < B[1] < ... < B[N-1]. # 3. All B[k] must be positive integers: B[k] >= 1. # # Let I = {i_1, i_2, ..., i_k} be the set of indices (0-based) where we keep the original values, i.e., B[i_j] = A[i_j]. # The indices must be sorted: 0 <= i_1 < i_2 < ... < i_k < N. # We must have B[i_j] < B[i_{j+1}] for all j. So A[i_j] < A[i_{j+1}}. # Also, there must exist values for the changed elements B[p] (p not in I) such that the whole sequence B is strictly increasing and positive. # For indices between i_j and i_{j+1}, we need B[i_j] < B[i_j + 1] < ... < B[i_{j+1} - 1] < B[i_{j+1}]. # This requires at least B[i_j] + (i_{j+1} - (i_j + 1) + 1) <= B[i_{j+1} - 1] < B[i_{j+1}]. # The number of elements between B[i_j] and B[i_{j+1}] is (i_{j+1} - 1) - (i_j + 1) + 1 = i_{j+1} - i_j - 1. # We need at least i_{j+1} - i_j steps of size 1 between B[i_j] and B[i_{j+1}]. # Thus, B[i_j] + (i_{j+1} - i_j) <= B[i_{j+1}}. # Since B[i_j] = A[i_j] and B[i_{j+1}] = A[i_{j+1}], this condition becomes A[i_j] + (i_{j+1} - i_j) <= A[i_{j+1}}. # Rearranging gives A[i_{j+1}] - i_{j+1} >= A[i_j] - i_j. # Let C[p] = A[p] - (p+1). Then the condition is C[i_{j+1}] >= C[i_j]. # # Additionally, we need B[k] >= 1 for all k. # For the first kept element A[i_1], we need B[0] < B[1] < ... < B[i_1-1] < B[i_1] = A[i_1]. # The minimum possible values for B[0]..B[i_1-1] are 1, 2, ..., i_1. # Thus, we need B[i_1-1] < B[i_1], which means i_1 < A[i_1]. # This is equivalent to A[i_1] >= i_1 + 1. # In terms of C values: C[i_1] = A[i_1] - (i_1+1) >= 0. # So, we need to find the longest subsequence of indices i_1 < i_2 < ... < i_k such that # A[i_1] >= i_1 + 1 (which implies C[i_1] >= 0) and C[i_j] <= C[i_{j+1}] for all j. # This is equivalent to finding the Longest Non-decreasing Subsequence (LNS) of the sequence C[i] # for those indices i where A[i] >= i + 1. # Create the filtered sequence of C values. C_filtered = [] for i in range(N): # Check the condition A[i] >= i + 1. # This ensures that A[i] is large enough to be placed at index i+1 in a strictly increasing sequence starting from 1. if A[i] >= i + 1: # Compute the transformed value C = A[i] - (i + 1). # Note that A[i] and i+1 are potentially large, but A[i] is positive. # The result C_val can be positive, zero, or negative. # The condition A[i] >= i+1 ensures C_val >= 0. C_val = A[i] - (i + 1) C_filtered.append(C_val) # Compute the length of the Longest Non-decreasing Subsequence (LNS) of C_filtered # We use the standard patience sorting based algorithm which takes O(L log L) time, # where L is the length of C_filtered (L <= N). tails = [] for x in C_filtered: # bisect_right(tails, x) finds an index `idx` such that all elements in `tails[:idx]` are <= x, # and all elements in `tails[idx:]` are > x. # This is the correct function for finding the place to update/insert for LNS. idx = bisect.bisect_right(tails, x) if idx == len(tails): # If x is greater than or equal to all elements currently in tails, # it means we can extend the longest non-decreasing subsequence found so far. tails.append(x) else: # If x is smaller than some element in tails, it means we found a potentially # better (smaller) ending value for a non-decreasing subsequence of length idx+1. # We replace tails[idx] with x. tails[idx] was the smallest element in tails # that is strictly greater than x. tails[idx] = x # The length of the LNS is the final size of the tails list. k = len(tails) # The maximum number of elements we can keep unchanged is k. # Therefore, the minimum number of elements we must change is N - k. print(N - k) # Execute the solve function solve()