#include #warning That's the baby, that's not my baby typedef long long ll; using namespace std; /** Solutie: Rotim la 45, acum ne fixam unul dintre cele K puncte. Observam ca va face cel mult n + m - 1 (< 2 * max(n, m)) pasi => ne vom uita pentru r pasi, care este intaltimea maxima la care putem ajunge. Practic avem un query de maxim pe un patrat din matrice => putem face rmq Complexitate temporala: O(N^2 * logN + K * N) **/ const int NMAX = 750; int a[NMAX + 1][NMAX + 1]; int b[2 * NMAX + 2][2 * NMAX + 2]; int rmqLine[12][2 * NMAX + 1][2 * NMAX + 1]; int rmqCol[12][2 * NMAX + 1][2 * NMAX + 1]; int lg2[2 * NMAX + 1]; int N; const int p2[14] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192}; int queryLine (int x, int l, int r) { l = max(l, 1); r = min(r, N); int k = lg2[r - l + 1]; return max(rmqLine[k][x][l], rmqLine[k][x][r - p2[k] + 1]); } int queryCol (int x, int l, int r) { l = max(l, 1); r = min(r, N); int k = lg2[r - l + 1]; return max(rmqCol[k][x][l], rmqCol[k][x][r - p2[k] + 1]); } int answer[NMAX * NMAX + 1]; int mini[2 * NMAX + 1]; int main() { ios_base::sync_with_stdio(false); cin.tie(0); int n, m, k; cin >> n >> m >> k; N = max(n, m); int maxel = 0; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> a[i][j]; b[i + j - 1][i - j + N] = a[i][j]; maxel = std::max(maxel, a[i][j]); } } N <<= 1; for (int i = 2; i <= N; i++) { lg2[i] = lg2[i >> 1] + 1; } for (int i = 1; i <= N; i++) { for (int j = 1; j <= N; j++) { if (!b[i][j]) { rmqLine[0][i][j] = rmqCol[0][j][i] = 1e9; } rmqLine[0][i][j] = rmqCol[0][j][i] = b[i][j]; // cout << setw(3) << b[i][j]; } // cout << '\n'; } for (int k = 1; p2[k] <= N; k++) { for (int i = 1; i <= N; i++) { for (int j = 1; j + p2[k] - 1 <= N; j++) { rmqLine[k][i][j] = max(rmqLine[k - 1][i][j], rmqLine[k - 1][i][j + p2[k - 1]]); } } for (int j = 1; j <= N; j++) { for (int i = 1; i + p2[k] - 1 <= N; i++) { rmqCol[k][j][i] = max(rmqCol[k - 1][j][i], rmqCol[k - 1][j][i + p2[k - 1]]); } } } for (int r = 1; r <= N; r++) { mini[r] = 1e9; } while (k--) { int x, y; cin >> x >> y; int i = x + y - 1; int j = x - y + N / 2; // cout << " ? " << b[i][j] << " - " << a[x][y] << '\n'; int cur = 0; for (int r = 1; r <= N; r++) { int x1 = i - r + 1, y1 = j - r + 1, x2 = i + r - 1, y2 = j + r - 1; if (x1 > 0) { cur = max(cur, queryLine(x1, y1, y2)); } if (x2 <= N) { cur = max(cur, queryLine(x2, y1, y2)); } if (y1 > 0) { cur = max(cur, queryCol(y1, x1, x2)); } if (y2 <= N) { cur = max(cur, queryCol(y2, x1, x2)); } mini[r] = min(mini[r], cur); } } for (int r = 1; r <= N; r++) { // cout << " > " << mini[r] << '\n'; if (mini[r] <= n * m) { answer[mini[r] + 1] = max(answer[mini[r] + 1], r); } } for (int i = 1; i <= n * m; i++) { answer[i] = max(answer[i], answer[i - 1]); if (i > maxel) { std::cout << "-1 "; } else { cout << answer[i] << ' '; } } return 0; } /** 6 5 6 30 14 11 22 16 7 5 6 3 23 20 1 5 2 17 21 1 4 2 6 17 7 3 24 3 26 25 13 14 10 2 2 3 2 4 4 5 5 2 4 4 3 **/