162 lines
3.4 KiB
C++
162 lines
3.4 KiB
C++
#include <bits/stdc++.h>
|
|
#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
|
|
|
|
**/
|