import sys from collections import deque def main(): input = sys.stdin.read().split() ptr = 0 H = int(input[ptr]); ptr +=1 W = int(input[ptr]); ptr +=1 gx = int(input[ptr])-1; ptr +=1 gy = int(input[ptr])-1; ptr +=1 A = [] for _ in range(H): row = list(map(int, input[ptr:ptr+W])) ptr += W A.append(row) Q = int(input[ptr]); ptr +=1 queries = [] for _ in range(Q): x = int(input[ptr])-1; ptr +=1 y = int(input[ptr])-1; ptr +=1 k = int(input[ptr]); ptr +=1 queries.append((x, y, k)) # Precompute for each cell (i, j) the list of (L, S) pairs # 4 directions dirs = [ (-1,0), (1,0), (0,-1), (0,1) ] # For each cell, store a list of (L, S) pairs # Initialize all cells with empty lists cells = [ [ [] for _ in range(W) ] for _ in range(H) ] # priority_queue will be a deque, and for BFS, perhaps use a queue of cells to process # Starting with the exit cell # exit cell's (gx, gy) # L=1, S=A[gx][gy] exit_i = gx exit_j = gy cells[exit_i][exit_j].append( (1, A[exit_i][exit_j]) ) # BFS queue: each entry is (i, j) from collections import deque q = deque() q.append( (exit_i, exit_j) ) # Visited is not needed because cells can be processed multiple times, as long as new (L, S) pairs are added # For processing in BFS-like order while q: i, j = q.popleft() # Explore neighbors for di, dj in dirs: ni = i + di nj = j + dj if 0 <= ni < H and 0 <= nj < W: # For each neighbor (ni, nj), we can generate new (L_new, S_new) = (L+1, S+A[ni][nj]) # Check all existing pairs in (i,j) # For each existing (L, S), generate new (L+1, S + A[ni][nj]) new_pairs = [] for L, S in cells[i][j]: L_new = L + 1 S_new = S + A[ni][nj] new_pairs.append( (L_new, S_new) ) # Now, merge these new_pairs into the neighbor's cells[ni][nj] # For each new (L_new, S_new): # Check if it's dominated by any existing pair in cells[ni][nj] # And if it can dominate some existing pairs. added = False for L_new, S_new in new_pairs: # Check against existing pairs # First, check if this new pair is not dominated by any existing pair dominated = False to_remove = [] for idx, (L_ex, S_ex) in enumerate(cells[ni][nj]): if L_ex <= L_new and S_ex <= S_new: dominated = True break if L_ex >= L_new and S_ex >= S_new: to_remove.append(idx) # Remove dominated pairs in reverse order for idx in reversed(to_remove): del cells[ni][nj][idx] if not dominated: # Now check if the new pair is not already in the list (but possibly with the same L and S) # Also, remove any existing pairs with L >= L_new and S >= S_new (dominated by new pair) # Now add the new pair cells[ni][nj].append( (L_new, S_new) ) added = True # After possible addition, sort the list by L, then S # Sort and remove duplicates if any if added: # Sort the cells[ni][nj] list by L, then by S cells[ni][nj].sort() # Remove duplicates: if same L, keep the one with smaller S unique = [] for p in cells[ni][nj]: if not unique or p[0] != unique[-1][0]: unique.append(p) elif p[0] == unique[-1][0] and p[1] < unique[-1][1]: unique.pop() unique.append(p) cells[ni][nj] = unique # Also, add the neighbor to the queue to process its neighbors q.append( (ni, nj) ) # Precompute convex hull for each cell hulls = [ [ [] for _ in range(W) ] for _ in range(H) ] for i in range(H): for j in range(W): # Build the convex hull for cells[i][j] points = cells[i][j] if not points: continue # Should not happen as per problem constraints, but safety # Sort points by L, then S points.sort() # Build lower convex hull hull = [] for p in points: L, S = p while len(hull) >= 2: # Check if the last two points and current point form a convex turn L1, S1 = hull[-2] L2, S2 = hull[-1] # Cross product: (L2 - L1) * (S - S2) - (L - L2) * (S2 - S1) # For lower hull, we want this to be >= 0 cross = (L2 - L1) * (S - S2) - (L - L2) * (S2 - S1) if cross <= 0: # Remove hull[-1] hull.pop() else: break hull.append( (L, S) ) hulls[i][j] = hull # Answer queries for x, y, k in queries: if x == exit_i and y == exit_j: # Already at exit print(A[x][y] + k*k) continue hull = hulls[x][y] if not hull: # Not reachable (should not happen per problem statement) print(0) continue c = k * k # Find the optimal (L, S) in hull which minimizes c*L + S # Since hull is sorted by L, and the lower envelope is convex, # the optimal point can be found via binary search left = 0 right = len(hull) - 1 best = None best_val = float('inf') # Check edge cases if len(hull) == 1: L, S = hull[0] print(c * L + S) continue # Binary search while left <= right: mid = (left + right) // 2 # Compute current value L_mid, S_mid = hull[mid] val_mid = L_mid * c + S_mid # Compare with next if mid < len(hull) -1: L_next, S_next = hull[mid+1] val_next = L_next * c + S_next if val_next < val_mid: left = mid +1 else: right = mid -1 else: right = mid -1 # Update best if val_mid < best_val: best_val = val_mid best = mid # Final check around the left region for i in range(max(0, left-2), min(len(hull), left+3)): if i <0 or i >= len(hull): continue L, S = hull[i] val = L * c + S if val < best_val: best_val = val print(best_val) if __name__ == '__main__': main()