Pagini recente » Cod sursa (job #2023550) | Cod sursa (job #1558728) | Cod sursa (job #2752798) | Cod sursa (job #285150) | Cod sursa (job #1533249)
#include <algorithm>
#include <fstream>
#include <cassert>
#include <vector>
using namespace std;
const int Nmax = 305, Mmax = 100005;
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
int A[Nmax][Nmax];
vector<int> G[Mmax];
int N;
pair<int, int> cells[Mmax];
int Father[Mmax], DSU[Mmax], Lvl[Mmax], Pos[Mmax];
int Asc[17][Mmax];
inline int getKey(int x, int y) {
return (x - 1) * N + y;
}
inline pair<int, int> getCell(int x) {
return make_pair((x - 1) / N + 1, (x - 1) % N + 1);
}
int find(int x) {
int y, p;
for (y = x; DSU[y] != y; y = DSU[y]);
for (; x != y; x = p) {
p = DSU[x];
DSU[x] = y;
}
return y;
}
int climb(int x, int nr) {
for (int k = 16; k >= 0; --k) {
if ((1 << k) <= nr) {
x = Asc[k][x];
nr -= 1 << k;
}
}
return x;
}
int lca(int x, int y) {
if (Lvl[x] < Lvl[y]) swap(x, y);
if (Lvl[x] > Lvl[y]) x = climb(x, Lvl[x] - Lvl[y]);
if (x == y) return x;
for (int k = 16; k >= 0; --k) {
if (Asc[k][x] != Asc[k][y]) {
x = Asc[k][x];
y = Asc[k][y];
}
}
return Asc[0][x];
}
int main() {
ifstream fin("matrice2.in");
ofstream fout("matrice2.out");
int Q;
fin >> N >> Q;
for (int i = 1; i <= N; ++i) {
for (int j = 1; j <= N; ++j) {
fin >> A[i][j];
cells[getKey(i, j)] = {A[i][j], getKey(i, j)};
}
}
sort(cells + 1, cells + N * N + 1);
for (int i = N * N; i > 0; --i) {
DSU[i] = i;
Father[i] = i;
Pos[cells[i].second] = i;
}
for (int i = N * N; i > 0; --i) {
pair<int, int> cell = getCell(cells[i].second);
int x = cell.first, y = cell.second, val = cells[i].first;
for (int k = 0; k < 4; ++k) {
int nx = x + dx[k], ny = y + dy[k];
if (nx < 1 || nx > N || ny < 1 || ny > N) continue;
int key = getKey(nx, ny);
if (Pos[key] > i) {
Father[find(key)] = cells[i].second;
DSU[find(key)] = cells[i].second;
}
}
}
int M = N * N;
for (int i = 1; i <= M; ++i) Asc[0][i] = Father[i];
for (int k = 1; k < 17; ++k) {
for (int i = 1; i <= M; ++i) {
Asc[k][i] = Asc[k - 1][Asc[k - 1][i]];
}
}
for (int i = 1; i <= M; ++i) {
pair<int, int> f = getCell(i), s = getCell(Father[i]);
assert(A[f.first][f.second] >= A[s.first][s.second]);
Lvl[cells[i].second] = Lvl[Father[cells[i].second]] + 1;
}
while (Q-- > 0) {
int x1, y1, x2, y2;
fin >> x1 >> y1 >> x2 >> y2;
int x = getKey(x1, y1), y = getKey(x2, y2);
pair<int, int> cell = getCell(lca(x, y));
fout << A[cell.first][cell.second] << '\n';
}
fin.close();
fout.close();
}