Pagini recente » Cod sursa (job #3001636) | Cod sursa (job #325591) | Cod sursa (job #467253) | Cod sursa (job #635565) | Cod sursa (job #322161)
Cod sursa(job #322161)
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
#define pb push_back
#define mp make_pair
#define x first
#define y second
#define forit(it, v) for (typeof(v.begin()) it = v.begin(); it != v.end(); ++it)
const int MAX_N = 300;
const int pow = 17;
int dir[4];
int n, m, root;
int f[MAX_N * MAX_N];
int val[MAX_N * MAX_N];
int t[MAX_N * MAX_N];
vector < pair <int, int> > v;
vector <int> fiu[MAX_N * MAX_N];
int lvl[MAX_N * MAX_N];
int b[pow][MAX_N * MAX_N];
int find(int nod)
{
if (t[nod] == nod) return nod;
return find(t[nod]);
}
void join(int c1, int c2)
{
t[c1] = c2;
}
inline int lg(int x) { return (x >> 1) ? lg(x >> 1) + 1 : 0; }
inline int lsb(int x) { return ((x ^ (x - 1)) + 1) >> 1; }
void build_tree()
{
int i, c1, c2;
forit(it, v)
{
t[it->y] = it->y;
f[it->y] = 1;
for (i = 0; i < 4; ++i)
{
int x = it->y + dir[i];
if (x < 0 || x >= n * n || (it->y / n != x / n && it->y % n != x % n)) continue;
if (f[x] && (c1 = find(x)) != (c2 = find(it->y)))
join(c1, c2);
}
}
}
void df(int nod)
{
if (f[nod]) return;
f[nod] = 1;
b[0][nod] = t[nod];
for (int i = 1; i < pow; ++i)
b[i][nod] = b[i - 1][b[i - 1][nod]];
forit(it, fiu[nod])
{
if (*it == nod) continue;
lvl[*it] = lvl[nod] + 1;
df(*it);
}
}
int lca(int x, int y)
{
if (lvl[x] > lvl[y])
x ^= y ^= x ^= y;
while (lvl[y] > lvl[x])
y = b[lg(lsb(lvl[y] - lvl[x]))][y];
if (x == y) return x;
for (int step = pow; step; --step)
if (b[step][x] != b[step][y])
x = b[step][x], y = b[step][y];
x = b[0][x];
y = b[0][y];
return x;
}
int main()
{
int i, j, x, x1, x2, y1, y2;
freopen("matrice2.in", "r", stdin);
freopen("matrice2.out", "w", stdout);
scanf("%d %d", &n, &m);
dir[0] = -n;
dir[1] = 1;
dir[2] = n;
dir[3]= -1;
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
{
scanf("%d", &x);
v.pb( mp(-x, i * n + j) );
}
sort(v.begin(), v.end());
forit(it, v)
{
it->x *= -1;
val[it->y] = it->x;
}
build_tree();
for (i = 0; i < n * n; ++i)
{
fiu[t[i]].pb(i);
if (i == t[i]) root = i;
}
memset(f, 0, sizeof(f));
lvl[root] = 0;
df(root);
for (i = 1; i <= m; ++i)
{
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
--x1; --x2; --y1; --y2;
printf("%d\n", val[lca(x1 * n + y1, x2 * n + y2)]);
}
}