結果
問題 |
No.1460 Max of Min
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:05:35 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 9,440 bytes |
コンパイル時間 | 145 ms |
コンパイル使用メモリ | 82,376 KB |
実行使用メモリ | 61,924 KB |
最終ジャッジ日時 | 2025-05-14 13:07:07 |
合計ジャッジ時間 | 4,184 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | TLE * 1 -- * 90 |
ソースコード
# -*- coding: utf-8 -*- import sys # Use fast I/O provided by sys.stdin.readline input = sys.stdin.readline def solve(): # Read K and N K, N = map(int, input().split()) # Read initial A values (A_0 to A_{K-1}) A = list(map(int, input().split())) # Read B values (B_0 to B_{K-1}) B = list(map(int, input().split())) # If N is less than K, A_N is one of the initial given values. if N < K: print(A[N]) return # The recurrence relation A_i = max(min(A_{i-K+j}, B_j) for 0 <= j < K) implies that # any A_i for i >= 0 must be one of the values from the initial A sequence or the B sequence. # Collect all unique initial values from A and B. possible_values = set(A) | set(B) # Sort these unique values to enable binary search. sorted_distinct_values = sorted(list(possible_values)) m = len(sorted_distinct_values) # Number of distinct possible values # Memoization dictionaries to cache results of matrix transpose and matrix power calculations. # This can significantly speed up computations if the same matrices or powers are needed multiple times. memo_transpose = {} memo_mat_pow = {} # Define matrix multiplication over the Boolean semiring (OR for addition, AND for multiplication). # Matrices are represented as lists of integers, where each integer is a bitmask representing a row. # K is the dimension of the square matrix. def mat_mul(mat1, mat2, K): # Use tuple representation of mat2 as key for memoizing its transpose. mat2_key = tuple(mat2) # Check cache for the transpose of mat2. if mat2_key in memo_transpose: mat2_T = memo_transpose[mat2_key] else: # If not cached, compute the transpose of mat2. # mat2_T[c] will store column c of mat2 as a bitmask. mat2_T = [0] * K for r in range(K): val_mat2_r = mat2[r] # Get the integer representing row r of mat2 for c in range(K): # Check if the c-th bit is set in row r. if (val_mat2_r >> c) & 1: # If yes, set the r-th bit in column c representation (mat2_T[c]). mat2_T[c] |= (1 << r) # Cache the computed transpose. memo_transpose[mat2_key] = mat2_T # Compute the resulting matrix product (mat1 * mat2). res = [0] * K for r in range(K): val_mat1_r = mat1[r] # Get the integer representing row r of mat1 # Optimization: if row r of mat1 is all zeros, the r-th row of the result is all zeros. if val_mat1_r == 0: res[r] = 0 continue row_res = 0 # Accumulator for the resulting row r bitmask for c in range(K): # The (r, c) entry of the result is 1 iff the dot product of row r of mat1 # and column c of mat2 is non-zero (in Boolean semiring: OR sum of AND products is 1). # This is equivalent to checking if the bitwise AND of mat1[r] and mat2_T[c] is non-zero. if (val_mat1_r & mat2_T[c]) != 0: # If non-zero, set the c-th bit in the resulting row r bitmask. row_res |= (1 << c) res[r] = row_res return res # Define matrix power using binary exponentiation (also known as exponentiation by squaring). def mat_pow(base, exp, K): # Use tuple representation of base matrix and exponent as key for memoization. base_key = tuple(base) state = (base_key, exp) # Return cached result if available. if state in memo_mat_pow: return memo_mat_pow[state] # Initialize result matrix 'res' as the identity matrix. res = [0] * K for i in range(K): res[i] = (1 << i) temp_base = base # Temporary variable to hold powers of base (base, base^2, base^4, ...) current_exp = exp # Current exponent value # Standard binary exponentiation loop. while current_exp > 0: # If the current exponent is odd, multiply the result by the current base power. if current_exp % 2 == 1: res = mat_mul(res, temp_base, K) # Square the current base power for the next iteration. temp_base = mat_mul(temp_base, temp_base, K) # Halve the exponent (integer division). current_exp //= 2 # Cache the computed result before returning. memo_mat_pow[state] = res return res # The problem asks for A_N. We use binary search on the possible values C. # For a given C, we check if A_N >= C. This check can be done using matrix exponentiation. # The state transition for the boolean sequence a_i = (A_i >= C) is linear over the Boolean semiring. # We need to compute the state M = N - K + 1 steps from the initial state. steps = N - K + 1 if steps < 0: steps = 0 # This should not happen for N >= K # This variable will store the index of the largest value C in sorted_distinct_values # for which the check A_N >= C returns true. Initialize to -1 (or another sentinel). current_best_idx = -1 # Perform an initial check with the minimum possible value C_min = sorted_distinct_values[0]. # We expect A_N >= C_min to be true based on the analysis that A_i values are bounded below. C_min = sorted_distinct_values[0] # Compute the boolean vector b where b_j = (B_j >= C_min). b_min = [(1 if B[j] >= C_min else 0) for j in range(K)] # Construct the transition matrix M_min for C_min. M_min = [0] * K for r in range(K - 1): M_min[r] = (1 << (r + 1)) # Shift rows row_K_minus_1_min = 0 for j in range(K): if b_min[j]: row_K_minus_1_min |= (1 << j) # Last row depends on b_min M_min[K-1] = row_K_minus_1_min # Compute the initial boolean state vector s0_min where s0_min_j = (A_j >= C_min). a0_min = [(1 if A[j] >= C_min else 0) for j in range(K)] s0_val_min = 0 for j in range(K): if a0_min[j]: s0_val_min |= (1 << j) # Calculate the state after 'steps' transitions. if steps == 0: # If N = K-1, the result A_N is A_{K-1}. Check its boolean value a_{K-1}. final_state_last_comp_val_min = (s0_val_min >> (K-1)) & 1 else: # Compute M_min ^ steps memo_transpose.clear() # Clear transpose cache before matrix power calculation M_pow_steps_min = mat_pow(M_min, steps, K) # The last component of the final state vector is a_N. # Calculate it as (last row of M_min^steps) AND s0_min, check if non-zero. final_state_last_comp_val_min = (M_pow_steps_min[K-1] & s0_val_min) != 0 # If A_N >= C_min is true, set the initial best index to 0. if final_state_last_comp_val_min: current_best_idx = 0 else: # This indicates a potential issue with the theory or implementation, as A_N should be >= min value. # For safety, output the minimal value found. print(sorted_distinct_values[0]) return # Perform binary search over the indices [0, m-1] of sorted_distinct_values. # We aim to find the largest index `mid_idx` such that A_N >= sorted_distinct_values[mid_idx]. low = current_best_idx # Start search from the minimum index known to work (initially 0). high = m - 1 while low <= high: mid_idx = (low + high) // 2 C = sorted_distinct_values[mid_idx] # The candidate value to check # Construct the boolean transition matrix M for this C. b = [(1 if B[j] >= C else 0) for j in range(K)] M = [0] * K for r in range(K - 1): M[r] = (1 << (r + 1)) # Shift rows row_K_minus_1 = 0 for j in range(K): if b[j]: row_K_minus_1 |= (1 << j) # Last row depends on b M[K-1] = row_K_minus_1 # Construct the initial boolean state vector s0 for this C. a0 = [(1 if A[j] >= C else 0) for j in range(K)] s0_val = 0 for j in range(K): if a0[j]: s0_val |= (1 << j) # Calculate the state after 'steps' transitions and find a_N. if steps == 0: # N = K-1 case final_state_last_comp_val = (s0_val >> (K-1)) & 1 else: # Compute M^steps memo_transpose.clear() # Clear transpose cache before matrix power calculation M_pow_steps = mat_pow(M, steps, K) # Check the value of a_N final_state_last_comp_val = (M_pow_steps[K-1] & s0_val) != 0 # Update binary search range based on the result. if final_state_last_comp_val: # If A_N >= C is true, C is a possible answer. Record this index. # Try potentially larger values C (increase lower bound). current_best_idx = mid_idx low = mid_idx + 1 else: # If A_N >= C is false, C is too high. # Need to check smaller values C (decrease upper bound). high = mid_idx - 1 # After binary search, current_best_idx holds the index of the largest C for which A_N >= C was true. # This C is the value of A_N. print(sorted_distinct_values[current_best_idx]) # Execute the solve function solve()