Pagini recente » Cod sursa (job #2713321) | Cod sursa (job #2825630) | Cod sursa (job #605206) | Cod sursa (job #1218884) | Cod sursa (job #2701625)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("matrice2.in");
ofstream fout("matrice2.out");
const int nmax = 305, qmax = 20005;
int n, q, mat[nmax][nmax], L[qmax], R[qmax], maxim, r[nmax * nmax], t[nmax * nmax], A[qmax], B[qmax], C[qmax], D[qmax];
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
int ans[qmax];
vector <int> Event[nmax * nmax];
vector <pair <int, int> > G[nmax * nmax];
unordered_map <int, int> mp, mpInv;
void normalize(){
vector <int> v;
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= n; ++j){
v.push_back(mat[i][j]);
}
}
sort(v.begin(), v.end());
int z = 1;
mp[v[0]] = z;
mpInv[z] = v[0];
for (int i = 1; i < v.size(); ++i){
if (v[i] != v[i - 1]){
++z;
}
mp[v[i]] = z;
mpInv[z] = v[i];
}
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= n; ++j){
mat[i][j] = mp[mat[i][j]];
}
}
}
bool Valid(int i, int j){
return i >= 1 && j >= 1 && i <= n && j <= n;
}
int GetParent(int nod)
{
int radacina = nod, copie_nod = nod;
while (t[nod] != nod)
{
radacina = t[nod];
nod = radacina;
}
while (t[copie_nod] != copie_nod)
{
int aux = t[copie_nod];
t[copie_nod] = radacina;
copie_nod = aux;
}
return radacina;
}
void Unite(int nod1, int nod2)
{
int parent1 = GetParent(nod1);
int parent2 = GetParent(nod2);
if (parent1 == parent2)
{
return;
}
if (r[parent1] > r[parent2])
{
t[parent2] = parent1;
}
else if (r[parent1] < r[parent2])
{
t[parent1] = parent2;
}
else
{
t[parent1] = parent2;
r[parent1]++;
}
}
void Clear(){
for (int i = 1; i <= maxim; ++i){
Event[i].clear();
}
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= n; ++j){
t[(i - 1) * n + j] = (i - 1) * n + j;
r[(i - 1) * n + j] = 0;
}
}
}
void Apply(int i){
for (auto it : G[i]){
int x = it.first;
int y = it.second;
for (int k = 0; k < 4; ++k){
int xx = x + dx[k];
int yy = y + dy[k];
if (Valid(xx, yy) && mat[xx][yy] >= i){
Unite((x - 1) * n + y, (xx - 1) * n + yy);
}
}
}
}
int main(){
fin >> n >> q;
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= n; ++j){
fin >> mat[i][j];
}
}
normalize();
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= n; ++j){
maxim = max(maxim, mat[i][j]);
G[mat[i][j]].push_back({i, j});
t[(i - 1) * n + j] = (i - 1) * n + j;
}
}
for (int i = 1; i <= q; ++i){
fin >> A[i] >> B[i] >> C[i] >> D[i];
L[i] = 1;
R[i] = maxim;
}
for (int l = 1; l <= maxim; l = l * 2){
Clear();
for (int i = 1; i <= q; ++i){
if (L[i] <= R[i]){
int mid = (L[i] + R[i]) / 2;
Event[mid].push_back(i);
}
}
for (int i = maxim; i >= 1; --i){
Apply(i);
for (auto it : Event[i]){
int nod1 = (A[it] - 1) * n + B[it];
int nod2 = (C[it] - 1) * n + D[it];
if (GetParent(nod1) == GetParent(nod2)){
L[it] = i + 1;
ans[it] = i;
}
else{
R[it] = i - 1;
}
}
}
}
for (int i = 1; i <= q; ++i){
fout << mpInv[ans[i]] << "\n";
}
fin.close();
fout.close();
return 0;
}