Pagini recente » Cod sursa (job #2687249) | Cod sursa (job #697424) | Cod sursa (job #1650665) | Cod sursa (job #2574709) | Cod sursa (job #3040163)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("matrice2.in");
ofstream fout("matrice2.out");
const int lgmax = 20;
const vector<int> dx = {1, -1, 0, 0};
const vector<int> dy = {0, 0, 1, -1};
struct deseu
{
vector<int> par;
vector<int> sz;
void resize(int n)
{
par = vector<int>(n + 1);
sz = vector<int>(n + 1);
}
void make_set(int x)
{
par[x] = x;
sz[x] = 1;
}
int find_set(int x)
{
if (par[x] == x)
{
return x;
}
return par[x] = find_set(par[x]);
}
void unite(int a, int b)
{
a = find_set(a);
b = find_set(b);
if (a != b)
{
if (sz[a] > sz[b])
{
swap(a, b);
}
par[a] = b;
sz[b] += sz[a];
}
}
};
struct query
{
int ans;
int x1;
int y1;
int x2;
int y2;
int ind;
bool operator<(query b) const
{
return ans > b.ans;
}
};
int32_t main()
{
cin.tie(nullptr)->sync_with_stdio(false);
int n, q;
fin >> n >> q;
vector<vector<int>> a(n + 1, vector<int>(n + 1));
vector<tuple<int, int, int>> pozitii;
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= n; ++j)
{
fin >> a[i][j];
pozitii.push_back({a[i][j], i, j});
}
}
sort(pozitii.begin(), pozitii.end(), greater<tuple<int, int, int>>());
vector<query> queries(q + 1);
for (int i = 1; i <= q; ++i)
{
int x1, y1, x2, y2;
fin >> x1 >> y1 >> x2 >> y2;
queries[i] = {0, x1, y1, x2, y2, i};
}
for (int bit = lgmax; bit >= 0; --bit)
{
sort(queries.begin() + 1, queries.end());
int p = 0;
deseu tree;
tree.resize(n * n);
for (int i = 1; i <= n * n; ++i)
{
tree.make_set(i);
}
vector<vector<int>> works(n + 1, vector<int>(n + 1));
function<void(int, int)> add = [&](int i, int j)
{
for (int k = 0; k < 4; ++k)
{
int cx = i + dx[k];
int cy = j + dy[k];
if (cx >= 1 && cx <= n && cy >= 1 && cy <= n && works[cx][cy])
{
tree.unite((i - 1) * n + j, (cx - 1) * n + cy);
}
}
};
for (int i = 1; i <= q; ++i)
{
while (p < (int)pozitii.size() && get<0>(pozitii[p]) >= queries[i].ans + (1 << bit))
{
works[get<1>(pozitii[p])][get<2>(pozitii[p])] = 1;
add(get<1>(pozitii[p]), get<2>(pozitii[p]));
p++;
}
if (tree.find_set((queries[i].x1 - 1) * n + queries[i].y1) == tree.find_set((queries[i].x2 - 1) * n + queries[i].y2))
{
queries[i].ans += (1 << bit);
}
}
}
vector<int> rep(q + 1);
for (int i = 1; i <= q; ++i)
{
rep[queries[i].ind] = queries[i].ans;
}
for (int i = 1; i <= q; ++i)
{
fout << rep[i] << '\n';
}
}