Pagini recente » Cod sursa (job #2540376) | Cod sursa (job #2727876) | Cod sursa (job #1564019) | Cod sursa (job #973610) | Cod sursa (job #2813270)
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;
ifstream fin ("matrice2.in");
ofstream fout ("matrice2.out");
//aceasta solutie utilizeaza trucul de "cautare binara paralela";
//-> explicatia tehnicii: https://codeforces.com/blog/entry/45578
int a[302][302];
struct el
{
int l, c, val;
} s[90001];
bool comp (const el &a, const el &b)
{
return a.val > b.val;
}
struct idk
{
int l1, c1, l2, c2;
int cst, cdr, cmij;
} intr[20001];
//intr[i].cst, intr[i].cdr sunt capetele cautarii binare pentru intrebarea i,
//cu cst si cdr aratand valorile din s[] intre care se afla raspunsul pentru intrebarea i
vector <int> ver[90001];
int t[90001], h[90001];
int cauta (int x);
void uneste (int x, int y);
int main()
{
int n, q, i, j, it, la, ca, lv, cv, x, y;
int dl[4] = {-1, 0, 1, 0};
int dc[4] = {0, 1, 0, -1};
fin >> n >> q;
for (i = 1; i<=n; i++)
for (j = 1; j<=n; j++)
{
fin >> a[i][j];
s[(i-1)*n + j] = {i, j, a[i][j]};
}
sort(s+1, s+n*n+1, comp);
for (i = 1; i<=q; i++)
{
fin >> intr[i].l1 >> intr[i].c1 >> intr[i].l2 >> intr[i].c2;
intr[i].cst = n*n;
intr[i].cdr = 1;
}
for (it = 1; (1<<(it-1)) < n*n; it++)
{
for (i = 1; i<=n*n; i++)
{
t[i] = h[i] = 0;
ver[i].clear();
}
for (i = 1; i<=q; i++)
if (intr[i].cst >= intr[i].cdr)
{
intr[i].cmij = (intr[i].cst + intr[i].cdr) >> 1;
ver[intr[i].cmij].push_back (i);
}
for (i = 1; i<=n*n; i++)
{
la = s[i].l;
ca = s[i].c;
for (j = 0; j<4; j++)
{
lv = la + dl[j];
cv = ca + dc[j];
if (lv >= 1 && lv <= n && cv >= 1 && cv <= n && a[lv][cv] >= s[i].val)
{
x = cauta ((la-1)*n + ca);
y = cauta ((lv-1)*n + cv);
if (x != y)
uneste (x, y);
}
}
for (j = 0; j<ver[i].size(); j++)
{
x = ver[i][j];
if (cauta ((intr[x].l1-1)*n + intr[x].c1) == cauta ((intr[x].l2-1)*n + intr[x].c2))
intr[x].cst = intr[x].cmij - 1;
else
intr[x].cdr = intr[x].cmij + 1;
}
}
}
for (i = 1; i<=q; i++)
fout << s[intr[i].cdr].val << '\n';
return 0;
}
int cauta (int x)
{
int r = x, y;
while (t[r])
r = t[r];
while (x != r)
{
y = t[x];
t[x] = r;
x = y;
}
return r;
}
void uneste (int x, int y)
{
if (h[x] < h[y])
t[x] = y;
else
{
t[y] = x;
if (h[x] == h[y])
h[x]++;
}
}