結果
問題 |
No.972 選び方のスコア
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:19:12 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 342 ms / 2,000 ms |
コード長 | 7,914 bytes |
コンパイル時間 | 471 ms |
コンパイル使用メモリ | 81,920 KB |
実行使用メモリ | 108,928 KB |
最終ジャッジ日時 | 2025-05-14 13:20:00 |
合計ジャッジ時間 | 8,756 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 32 |
ソースコード
import sys def solve(): N = int(sys.stdin.readline()) # Handle edge case N=0 although constraints state N >= 1. # If N=0, the list 'a' would be empty. We cannot select k>=1 elements. # If N=1, we must select the single element. k=1. median m = a_1. score = a_1 - m = 0. # The code should handle N=1 correctly. If N=0, it might error; let's assume N>=1. if N == 0: print(0) return A = list(map(int, sys.stdin.readline().split())) A.sort() # Sort the array to easily find median and work with indices # Calculate prefix sums to efficiently compute sum over ranges. # P[i] stores the sum of A[0]...A[i-1]. P[0] = 0. # The sum of elements A[L..R] (0-based indices) is P[R+1] - P[L]. P = [0] * (N + 1) for i in range(N): P[i+1] = P[i] + A[i] max_S = 0 # Initialize maximum score found so far # Case 1: The number of selected elements k is odd. Let k = 2j + 1. # The median m is the element at index (k+1)/2 = j+1 in the sorted selected list. # We iterate through each element A[p_idx] of the sorted array A and consider it as the median element. for p_idx in range(N): p_val = A[p_idx] # The value of the potential median element. # To make A[p_idx] the median of k=2j+1 elements, we must select A[p_idx] itself, # j elements less than or equal to A[p_idx], and j elements greater than or equal to A[p_idx]. # To maximize the score S = sum(b_i - m), we should select: # - The j largest elements from A[0...p_idx-1] (these are A[p_idx-j ... p_idx-1]). # - The j largest elements from A[p_idx+1...N-1] (these are A[N-j ... N-1]). # This strategy requires that we have at least j elements to the left and right of A[p_idx]. # Number of elements left = p_idx. Number of elements right = N - 1 - p_idx. # Thus, the maximum possible value for j is min(p_idx, N - 1 - p_idx). max_j_limit = min(p_idx, N - 1 - p_idx) optimal_j = 0 # Tracks the largest j satisfying the score increase condition. Initialized to 0 (k=1 case). # We use binary search to find the optimal value of j. The score function S_j is concave with respect to j. # We look for the largest j such that increasing j further improves the score. # The condition for improvement S_j > S_{j-1} is equivalent to A[p_idx - j] + A[N - j] > 2 * p_val. low = 0 high = max_j_limit current_optimal_j = 0 # Store the best j found in this binary search loop. Initialized to 0. while low <= high: j = (low + high) // 2 if j == 0: # j=0 corresponds to k=1. The score is always 0. This is a valid base case. # Check if larger j values can satisfy the condition. current_optimal_j = max(current_optimal_j, j) # Ensure 0 is considered low = j + 1 continue # Condition check using 0-based indices: idx1 = p_idx - j idx2 = N - j # Check validity of indices (though should be guaranteed by max_j_limit) # if idx1 < 0 or idx2 >= N: continue # Safety check if A[idx1] + A[idx2] > 2 * p_val: # If the condition holds, increasing j to this value improved the score. # This j is potentially optimal, try larger j values. current_optimal_j = max(current_optimal_j, j) low = j + 1 # Explore larger j else: # If the condition does not hold, this j (and larger values) do not improve score. Search smaller j. high = j - 1 optimal_j = current_optimal_j # The largest j that satisfies the condition. best_j = optimal_j # Calculate the score S for this best_j. # S_j = sum(A[p_idx-j .. p_idx-1]) + sum(A[N-j .. N-1]) - 2*j*A[p_idx] # Use prefix sums for range sums: sum(A[L..R]) = P[R+1] - P[L] term1 = P[p_idx] - P[p_idx - best_j] # Sum A[p_idx-best_j .. p_idx-1] term2 = P[N] - P[N - best_j] # Sum A[N-best_j .. N-1] current_S = term1 + term2 - 2 * best_j * p_val max_S = max(max_S, current_S) # Update overall maximum score # Case 2: The number of selected elements k is even. Let k = 2j. # The median m is the average of the two middle elements: (x_{k/2} + x_{k/2+1}) / 2 = (x_j + x_{j+1}) / 2. # We iterate through each pair of adjacent elements (A[p_idx], A[p_idx+1]) and consider them as the median pair (x_j, x_{j+1}). for p_idx in range(N - 1): p_val1 = A[p_idx] # Value of the first median element candidate p_val2 = A[p_idx+1] # Value of the second median element candidate # To make (A[p_idx], A[p_idx+1]) the median pair of k=2j elements, we must select them, # j-1 elements <= A[p_idx], and j-1 elements >= A[p_idx+1]. # To maximize score S = sum(b_i - m), we should select: # - The j-1 largest elements from A[0...p_idx-1] (these are A[p_idx-(j-1) ... p_idx-1]). # - The j-1 largest elements from A[p_idx+2...N-1] (these are A[N-(j-1) ... N-1]). # Requires j-1 elements available left and right. # Number of elements left of A[p_idx] is p_idx. So j-1 <= p_idx => j <= p_idx + 1. # Number of elements right of A[p_idx+1] is N - 1 - (p_idx+1) = N - p_idx - 2. So j-1 <= N - p_idx - 2 => j <= N - p_idx - 1. # Maximum possible j is min(p_idx + 1, N - p_idx - 1). max_j_limit = min(p_idx + 1, N - 1 - p_idx) # Need k=2j >= 1. Since k is even, minimal k is 2, so minimal j is 1. if max_j_limit < 1: continue # If max possible j is less than 1, we cannot form a pair (k>=2). optimal_j = 1 # Default optimal j is 1 (k=2), which always gives score 0. # Binary search for the largest j in [2, max_j_limit]. # The score S'_j is concave w.r.t. j. We look for the largest j where S'_j > S'_{j-1}. # This condition is equivalent to A[p_idx - j + 1] + A[N - j + 1] > p_val1 + p_val2. low = 2 # Start search from j=2, as j=1 is the base case. high = max_j_limit current_optimal_j = 1 # Store the best j found in this BS loop, initialized to 1. while low <= high: j = (low + high) // 2 # Condition check using 0-based indices: idx1 = p_idx - j + 1 idx2 = N - j + 1 # Check validity of indices (guaranteed by range and max_j_limit logic) # if idx1 < 0 or idx2 >= N: continue # Safety check if A[idx1] + A[idx2] > p_val1 + p_val2: # If condition holds, this j>=2 improved the score. Potentially optimal. Try larger j. current_optimal_j = max(current_optimal_j, j) low = j + 1 else: # Condition fails, this j and larger won't improve score. Search smaller j. high = j - 1 optimal_j = current_optimal_j # The best j found (at least 1). best_j = optimal_j # Calculate score S'_j for the determined best_j. # S'_j = sum(A[p_idx-j+1 .. p_idx-1]) + A[p_idx] + A[p_idx+1] + sum(A[N-j+1 .. N-1]) - j*(A[p_idx]+A[p_idx+1]) # Use prefix sums: term1 = P[p_idx] - P[p_idx - best_j + 1] # Sum A[p_idx-best_j+1 .. p_idx-1] term2 = P[N] - P[N - best_j + 1] # Sum A[N-best_j+1 .. N-1] # Note: The sums are empty if the start index exceeds the end index (e.g., when best_j=1). P[x] - P[x] = 0. current_S = term1 + p_val1 + p_val2 + term2 - best_j * (p_val1 + p_val2) max_S = max(max_S, current_S) # Update overall maximum score print(max_S) solve()