Pagini recente » Cod sursa (job #2361321) | Cod sursa (job #1846964) | Cod sursa (job #2467631) | Cod sursa (job #1873124) | Cod sursa (job #1207839)
#include <cstdio>
#include <iostream>
#include <fstream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <string>
#include <ctime>
#include <cassert>
#include <utility>
using namespace std;
#define MAXN 305
#define MAXQ 20050
struct Query {
int idx1, idx2;
int st, dr;
int ans;
int qid;
Query(int idx1, int idx2, int n, int qid) : idx1(idx1), idx2(idx2), qid(qid) {
st = 0;
dr = n * n - 1;
ans = -1;
}
int mid() {
return (st + dr) / 2;
}
};
int N, Q;
int A[MAXN][MAXN];
pair<int, pair<int, int> > B[MAXN * MAXN];
int X1, Y1, X2, Y2;
vector<Query> qs;
int T[MAXN * MAXN];
int ans[MAXQ];
const int di[] = { 1, 0, -1, 0 };
const int dj[] = { 0, 1, 0, -1 };
bool comp(const Query &a, const Query &b) {
int ma = (a.st + a.dr) / 2;
int mb = (b.st + b.dr) / 2;
return ma < mb;
}
int root(int t) {
if (T[t] != t) {
T[t] = root(T[t]);
}
return T[t];
}
void unite(int ra, int rb) {
if (ra == rb) {
return;
}
if (rand() & 1) {
T[ra] = rb;
}
else {
T[rb] = ra;
}
}
int main() {
freopen("matrice2.in", "r", stdin);
freopen("matrice2.out","w", stdout);
srand(time(NULL));
scanf("%d %d", &N, &Q);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
scanf("%d", &A[i][j]);
B[i * N + j] = make_pair(A[i][j], make_pair(i, j));
}
}
sort(B, B + N * N);
for (int i = 0; i < Q; i++) {
scanf("%d %d %d %d", &X1, &Y1, &X2, &Y2);
X1--; Y1--; X2--; Y2--;
qs.push_back(Query(X1 * N + Y1, X2 * N + Y2, N, i));
}
bool ok = true;
while (ok) {
ok = false;
sort(qs.begin(), qs.end(), comp);
for (int i = 0; i < N * N; i++) {
T[i] = i;
}
int j = Q - 1;
for (int i = N * N - 1; i >= 0; i--) {
int pi = B[i].second.first;
int pj = B[i].second.second;
int idx = pi * N + pj;
for (int d = 0; d < 4; d++) {
int ni = pi + di[d];
int nj = pj + dj[d];
if (ni >= 0 && ni < N && nj >= 0 && nj < N && A[pi][pj] <= A[ni][nj]) {
int nidx = ni * N + nj;
unite(root(idx), root(nidx));
}
}
while (j >= 0 && qs[j].mid() == i) {
if (qs[j].st > qs[j].dr) {
j--;
continue;
}
ok = true;
int a = qs[j].idx1;
int b = qs[j].idx2;
int m = qs[j].mid();
if (root(a) == root(b)) {
qs[j].ans = m;
qs[j].st = m + 1;
}
else {
qs[j].dr = m - 1;
}
j--;
}
}
}
for (int i = 0; i < Q; i++) {
int crt = B[qs[i].ans].first;
crt = min(crt, A[qs[i].idx1 / N][qs[i].idx1 % N]);
crt = min(crt, A[qs[i].idx2 / N][qs[i].idx2 % N]);
ans[qs[i].qid] = crt;
}
for (int i = 0; i < Q; i++) {
printf("%d\n", ans[i]);
}
return 0;
}