結果
問題 |
No.1215 都市消滅ビーム
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:06:41 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 7,114 bytes |
コンパイル時間 | 148 ms |
コンパイル使用メモリ | 83,036 KB |
実行使用メモリ | 77,236 KB |
最終ジャッジ日時 | 2025-05-14 13:08:00 |
合計ジャッジ時間 | 9,465 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | -- * 2 |
other | AC * 13 TLE * 1 -- * 26 |
ソースコード
import sys # Increase recursion depth limit for deep trees, although BFS avoids stack overflow. # The LCA part might use recursion implicitly depending on implementation details, but typically not. # Setting it high just in case some part of the system uses deep recursion. # sys.setrecursionlimit(200005) def solve(): N, K = map(int, sys.stdin.readline().split()) # Read temple locations C and values D # Cities are 1-based indexed in input, keep them as is. C = list(map(int, sys.stdin.readline().split())) D = list(map(int, sys.stdin.readline().split())) # Build adjacency list for the tree adj = {} def add_edge(u, v): if u not in adj: adj[u] = [] if v not in adj: adj[v] = [] adj[u].append(v) adj[v].append(u) for _ in range(N - 1): u, v = map(int, sys.stdin.readline().split()) add_edge(u, v) # If K=0 (no temples), the problem statement says X = -10^(10^10). # However, constraints state K >= 2. So K=0 case is not possible per constraints. # Precomputation for LCA and depths using BFS # Determine the maximum required power of 2 for LCA jump pointers MAX_LOG_N = (N).bit_length() # parent[i][j] stores the 2^i-th ancestor of node j parent = [[0] * (N + 1) for _ in range(MAX_LOG_N)] # depth[j] stores the depth of node j (distance from root 1) depth = [-1] * (N + 1) # BFS queue stores tuples: (current_node, parent_node, depth_value) queue = [(1, 0, 0)] # Keep track of visited nodes to avoid cycles (though it's a tree) visited = {1} depth[1] = 0 # parent[0][1] = 0 signifies root 1 has no parent (or a dummy parent 0) parent[0][1] = 0 head_idx = 0 while head_idx < len(queue): curr, p, d = queue[head_idx] head_idx += 1 # Set the immediate parent (2^0 ancestor) parent[0][curr] = p depth[curr] = d # Explore neighbors if curr in adj: for neighbor in adj[curr]: # Avoid going back to the parent node if neighbor != p: if neighbor not in visited: visited.add(neighbor) queue.append((neighbor, curr, d + 1)) # Fill the parent table for LCA using dynamic programming # Calculate 2^i-th ancestor based on 2^(i-1)-th ancestors for i in range(1, MAX_LOG_N): for j in range(1, N + 1): # The 2^i-th ancestor of j is the 2^(i-1)-th ancestor of its 2^(i-1)-th ancestor. # Check if the intermediate ancestor exists (is not 0) if parent[i-1][j] != 0: parent[i][j] = parent[i - 1][parent[i - 1][j]] # LCA function using binary lifting def lca(u, v): # Ensure u and v are valid nodes if u == 0 or v == 0: return 0 # Ensure u is the deeper node (or equal depth) if depth[u] < depth[v]: u, v = v, u # Lift node u up to the same depth as v diff = depth[u] - depth[v] # Use bit manipulation to check powers of 2 for i in range(MAX_LOG_N): if (diff >> i) & 1: u = parent[i][u] # If u and v are the same node now, it's the LCA if u == v: return u # Lift both u and v simultaneously keeping them below the LCA # Iterate from largest power of 2 down to 0 for i in range(MAX_LOG_N - 1, -1, -1): # If 2^i-th parents are different, lift both nodes if parent[i][u] != parent[i][v]: u = parent[i][u] v = parent[i][v] # After the loop, u and v are direct children of the LCA # The LCA is the immediate parent of u (or v) return parent[0][u] # Define a sentinel value for the case of no temples. # Choose a value smaller than any possible X. Min possible X can be approx -K * 10^9 + 0. # So -10^5 * 10^9 = -10^14. A value like -2 * 10^18 is safe. SENTINEL = -3 * 10**18 # Store calculated X values for all possible operations X_values = [] # Helper function to compute X for a given set of temple indices (0-based) def compute_X(temple_indices): # If no temples remain, return sentinel value if not temple_indices: return SENTINEL # Get the list of cities where remaining temples are located current_cities = [C[i] for i in temple_indices] # Calculate the sum of values of remaining temples current_S = sum(D[i] for i in temple_indices) # Compute the LCA of all cities with remaining temples # Start with the first city current_T = current_cities[0] # Iteratively compute LCA with subsequent cities for idx in range(1, len(current_cities)): current_T = lca(current_T, current_cities[idx]) # Handle potential issue if LCA returns 0 (should not happen for valid tree and nodes 1..N) if current_T == 0: # This might indicate an issue, return sentinel or handle error appropriately # Depending on tree structure, lca(1, node) = 1. # If LCA logic is correct, this shouldn't happen unless graph disconnected or nodes outside 1..N used. return SENTINEL # Indicate error/undefined state # Final X value is sum S + depth of LCA node T # Ensure current_T is within valid range [1, N] before accessing depth if not (1 <= current_T <= N): return SENTINEL # Error case return current_S + depth[current_T] # Case 0: No removal of temples # All temples initially present. Indices are 0 to K-1. X_values.append(compute_X(list(range(K)))) # Cases 1 to K*(K+1)/2: Removing temples with index from l to r (inclusive) # Temple indices are 1-based in problem statement, l and r are 1-based. for l in range(1, K + 1): # l loops from 1 to K for r in range(l, K + 1): # r loops from l to K # Determine indices of remaining temples (0-based) current_temples_indices = [] for i in range(K): # i is the 0-based index # The problem refers temple indices 1..K. So temple `i+1` is considered. # Check if temple `i+1` is NOT in the range [l, r] to be removed. if not (l <= i + 1 <= r): current_temples_indices.append(i) # Compute X for the remaining temples X_values.append(compute_X(current_temples_indices)) # Sort all computed X values X_values.sort() # The total number of operations is K*(K+1)/2 + 1. # The median is the element at rank floor((total_count + 1) / 2). # Calculate the 0-based index for the median value. total_count = len(X_values) median_idx = (total_count + 1) // 2 - 1 # Print the median value print(X_values[median_idx]) # Call the main solver function solve()