1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| #include <iostream> #include <cmath> #include <vector> #include <algorithm> #include <tuple> #define maxm 1010 #define maxn 1000010 #define Maxn 2000010 #define ll long long using namespace std;
int n, m, g[maxm][maxm], s[maxm][maxm], r[maxm][maxm]; char str[maxm];
inline int id(int x, int y) { return (x - 1) * n + y; }
inline bool check(int x1, int x2, int y1, int y2) { return s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1] == 0; }
int fa[Maxn]; void init_fa(int n) { for (int i = 1; i <= n; ++i) fa[i] = i; } int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
vector<int> G[Maxn]; int w[Maxn], top, dep[Maxn], f[Maxn][21]; void dfs(int u, int fa) { for (auto v : G[u]) { if (v == fa) continue; dep[v] = dep[u] + 1; f[v][0] = u; dfs(v, u); } }
void init_lca(int n) { for (int j = 1; j <= 20; ++j) for (int i = 1; i <= n; ++i) f[i][j] = f[f[i][j - 1]][j - 1]; } int get_lca(int x, int y) { if (dep[x] < dep[y]) swap(x, y); for (int i = 20; ~i; --i) if (dep[f[x][i]] >= dep[y]) x = f[x][i]; if (x == y) return x; for (int i = 20; ~i; --i) if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i]; return f[x][0]; }
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> n; for (int i = 1; i <= n; ++i) { cin >> str + 1; for (int j = 1; j <= n; ++j) g[i][j] = str[j] == '#'; } for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) s[i][j] += g[i][j] + s[i - 1][j]; for (int j = 1; j <= n; ++j) for (int i = 1; i <= n; ++i) s[i][j] += s[i][j - 1]; for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) { if (g[i][j]) continue; int l = 1, r = min({ i, j, n - i + 1, n - j + 1 }), mid, ans; while (l <= r) { mid = l + r >> 1; if (check(i - mid + 1, i + mid - 1, j - mid + 1, j + mid - 1)) ans = mid, l = mid + 1; else r = mid - 1; } ::r[i][j] = ans; } vector<tuple<int, int, int>> vec; int dx[] = { -1, 1, 0, 0 }, dy[] = { 0, 0, 1, -1 }; for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) for (int k = 0; k < 4; ++k) { int x = i + dx[k], y = j + dy[k]; if (x < 1 || x > n || y < 1 || y > n) continue; if (g[i][j] || g[x][y]) continue; if (r[i][j] > r[x][y]) continue; vec.emplace_back(r[i][j], id(i, j), id(x, y)); } sort(vec.begin(), vec.end()), reverse(vec.begin(), vec.end()); init_fa(2 * n * n); top = n * n; for (auto [w, u, v] : vec) { int fu = find(u), fv = find(v); if (fu == fv) continue; fa[fu] = fa[fv] = ++top; ::w[top] = w; G[top].push_back(fu), G[top].push_back(fv); } for (int i = 1; i <= top; ++i) if (find(i) == i) dep[i] = 1, dfs(i, 0); init_lca(top); cin >> m; for (int i = 1; i <= m; ++i) { int x1, x2, y1, y2; cin >> x1 >> y1 >> x2 >> y2; if (g[x1][y1] || g[x2][y2]) { cout << 0 << "\n"; continue; } int u = id(x1, y1), v = id(x2, y2); if (find(u) != find(v)) { cout << 0 << "\n"; continue; } int k = get_lca(u, v); cout << 2 * w[get_lca(u, v)] - 1 << "\n"; } return 0; }
|