結果
問題 |
No.2786 RMQ on Grid Path
|
ユーザー |
![]() |
提出日時 | 2025-03-31 17:28:06 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 3,874 ms / 6,000 ms |
コード長 | 3,549 bytes |
コンパイル時間 | 460 ms |
コンパイル使用メモリ | 82,644 KB |
実行使用メモリ | 318,360 KB |
最終ジャッジ日時 | 2025-03-31 17:29:49 |
合計ジャッジ時間 | 74,562 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 35 |
ソースコード
import sys from sys import stdin from collections import deque def main(): H, W = map(int, stdin.readline().split()) grid = [] for _ in range(H): row = list(map(int, stdin.readline().split())) grid.append(row) edges = [] for i in range(H): for j in range(W): current = i * W + j current_val = grid[i][j] if i < H - 1: ni, nj = i + 1, j neighbor = ni * W + nj weight = max(current_val, grid[ni][nj]) edges.append((weight, current, neighbor)) if j < W - 1: ni, nj = i, j + 1 neighbor = ni * W + nj weight = max(current_val, grid[ni][nj]) edges.append((weight, current, neighbor)) edges.sort() parent = list(range(H * W)) def find(u): while parent[u] != u: parent[u] = parent[parent[u]] u = parent[u] return u mst_edges = [] for weight, u, v in edges: u_root = find(u) v_root = find(v) if u_root != v_root: parent[v_root] = u_root mst_edges.append((u, v, weight)) mst_edges.append((v, u, weight)) adj = [[] for _ in range(H * W)] for u, v, w in mst_edges: adj[u].append((v, w)) root = 0 parent_list = [-1] * (H * W) edge_weight = [0] * (H * W) depth = [0] * (H * W) queue = deque([root]) parent_list[root] = -1 depth[root] = 0 while queue: u = queue.popleft() for v, w in adj[u]: if parent_list[v] == -1 and v != parent_list[u]: parent_list[v] = u edge_weight[v] = w depth[v] = depth[u] + 1 queue.append(v) MAX_LOG = 20 jump = [[-1] * (H * W) for _ in range(MAX_LOG)] max_edge = [[0] * (H * W) for _ in range(MAX_LOG)] for u in range(H * W): jump[0][u] = parent_list[u] max_edge[0][u] = edge_weight[u] for k in range(1, MAX_LOG): for u in range(H * W): if jump[k-1][u] != -1: jump[k][u] = jump[k-1][jump[k-1][u]] max_edge[k][u] = max(max_edge[k-1][u], max_edge[k-1][jump[k-1][u]]) else: jump[k][u] = -1 max_edge[k][u] = 0 def get_lca(u, v): if depth[u] < depth[v]: u, v = v, u for k in reversed(range(MAX_LOG)): if depth[u] - (1 << k) >= depth[v]: u = jump[k][u] if u == v: return u for k in reversed(range(MAX_LOG)): if jump[k][u] != -1 and jump[k][u] != jump[k][v]: u = jump[k][u] v = jump[k][v] return jump[0][u] def get_max(u, anc): if u == anc: return 0 max_e = 0 current = u for k in reversed(range(MAX_LOG)): if depth[current] - (1 << k) >= depth[anc]: max_e = max(max_e, max_edge[k][current]) current = jump[k][current] return max_e Q = int(stdin.readline()) for _ in range(Q): rs, cs, rt, ct = map(int, stdin.readline().split()) rs -= 1 cs -= 1 rt -= 1 ct -= 1 u = rs * W + cs v = rt * W + ct lca = get_lca(u, v) max_u = get_max(u, lca) max_v = get_max(v, lca) print(max(max_u, max_v)) if __name__ == "__main__": main()