Pagini recente » Cod sursa (job #1255532) | Cod sursa (job #1137851) | Cod sursa (job #2870833) | Cod sursa (job #1255536) | Cod sursa (job #1424139)
#include <fstream>
#include <algorithm>
#include <utility>
#include <cstring>
#define NMAX 305
#define QMAX 20005
using namespace std;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
int n;
int mat[NMAX][NMAX];
class disjoint_sets {
pair <int, int> mat[NMAX][NMAX];
int h[NMAX][NMAX];
pair <int, int> find (const pair <int, int> &cell) {
if (mat[cell.first][cell.second] != cell)
mat[cell.first][cell.second] = find(mat[cell.first][cell.second]);
return mat[cell.first][cell.second];
}
inline void unite (pair <int, int> cell1, pair <int, int> cell2) {
cell1 = find(cell1);
cell2 = find(cell2);
if (cell1 == cell2)
return ;
if (h[cell1.first][cell1.second] < h[cell2.first][cell2.second])
mat[cell1.first][cell1.second] = cell2;
else {
mat[cell2.first][cell2.second] = cell1;
if (h[cell1.first][cell1.second] == h[cell2.first][cell2.second])
h[cell1.first][cell1.second] ++;
}
}
public:
inline void init () {
memset(h, 0, sizeof(h));
int j;
for (int i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
mat[i][j] = make_pair(i, j);
}
disjoint_sets () {
init();
}
inline void insert (const pair <int, int> &cell) {
h[cell.first][cell.second] = 1;
pair <int, int> aux;
for (int k = 0; k < 4; k++) {
aux.first = cell.first + dx[k];
aux.second = cell.second + dy[k];
if (aux.first > 0 && aux.second > 0 && aux.first <= n && aux.second <= n && h[aux.first][aux.second])
unite(cell, aux);
}
}
inline bool united (pair <int, int> cell1, pair <int, int> cell2) {
cell1 = find(cell1);
cell2 = find(cell2);
return (cell1 == cell2);
}
} Sets;
pair <int, int> elements[NMAX * NMAX];
bool cmp (const pair <int, int> &cell1, const pair <int, int> &cell2) {
return mat[cell1.first][cell1.second] > mat[cell2.first][cell2.second];
}
int q;
struct query {
pair <int, int> cell1, cell2;
int pos;
} queries[QMAX], aux1[QMAX], aux2[QMAX];
int answers[QMAX];
bool operator< (const query &a, const query &b) {
return answers[a.pos] > answers[b.pos];
}
int main()
{
ifstream cin("matrice2.in");
ofstream cout("matrice2.out");
cin >> n >> q;
int j;
for (int i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
cin >> mat[i][j];
for (int i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
elements[(i - 1) * n + j] = make_pair(i, j);
sort(elements + 1, elements + n * n + 1, cmp);
for (int i = 1; i <= q; i++) {
cin >> queries[i].cell1.first >> queries[i].cell1.second >> queries[i].cell2.first >> queries[i].cell2.second;
queries[i].pos = i;
}
//Parallel binary search
int k, aux1l, aux2l;
for (int i = 20; i >= 0; i--) { //Incercam sa adaugam (1 << i)
Sets.init();
for (j = 1; j <= q; j++)
answers[queries[j].pos] += (1 << i);
k = 0;
aux1l = 0, aux2l = 0;
for (j = 1; j <= q; j++) {
while (k + 1 <= n * n && mat[elements[k + 1].first][elements[k + 1].second] >= answers[queries[j].pos]) {
k ++;
Sets.insert(elements[k]);
}
if (Sets.united(queries[j].cell1, queries[j].cell2))
aux1[++ aux1l] = queries[j];
else {
aux2[++ aux2l] = queries[j];
answers[queries[j].pos] -= (1 << i);
}
}
//Resortam query-urile
merge(aux1 + 1, aux1 + aux1l + 1, aux2 + 1, aux2 + aux2l + 1, queries + 1);
}
//
for (int i = 1; i <= q; i++)
cout << answers[i] << '\n';
cin.close();
cout.close();
return 0;
}