Cod sursa(job #1072070)

Utilizator ELHoriaHoria Cretescu ELHoria Data 3 ianuarie 2014 21:46:54
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.62 kb
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <unordered_set>
#include <set>

using namespace std;
  

const int dx[] = {-1,1,0,0};
const int dy[] = {0,0,-1,1};
const int nmax = 300;
unordered_set<int> h[nmax * nmax];
vector<int> P[nmax * nmax];
int ans[20005];
int T[nmax * nmax];
int M[nmax][nmax];
int N;
int Q;
int K;
int A[nmax * nmax];

void printQ(ostream &cout) {
	for (int i = 0;i < N;i++) {
		for (int j = 0;j < N;j++) {
			if (!h[i*N + j].empty()) {
				cout << i << "  " << j << " :\n";
				for (const int &q : h[i * N + j]) {
					cout << q << "\n";
				}
				cout << "\n";
			}
		}
	}
}

int getRoot(int x,const int &height) {
	int r = x;
	while (r != T[r]) r = T[r];
	while (x != T[x]) {
		int aux = T[x];
		T[x] = r;
		if (!h[x].empty()) {
			for (const int &q : h[x]) {
				auto it = h[r].find(q);
				if (it != h[r].end()) {
					h[r].erase(it);
					ans[q] = A[height];
					
				} else {
					h[r].insert(q);
				}
			}
			h[x].clear();
		}

		x = aux;
	
	}
	return r;
}

void unite(int x,int y,const int &height) {
	if (x == y) return;
	if (A[M[x / N][x % N]] > A[M[y / N][y % N]]) swap(x,y);

	if (h[x].size() < h[y].size()) {
		h[x].swap(h[y]);
	}

	for (const int &q : h[y]) {
		auto it = h[x].find(q);
		if (it != h[x].end()) {
			h[x].erase(it);
			ans[q] = A[height];
		} else {
			h[x].insert(q);
		}
	}

	h[y].clear();
	T[y] = x;
}
  
int main()
{
	ifstream cin("matrice2.in");
	ofstream cout("matrice2.out");
	cin >> N >> Q;
	set<int> s;
	for (int i = 0;i < N;i++) {
		for (int j = 0;j < N;j++) {
			cin >> M[i][j];
			s.insert(M[i][j]);
		}
	}
	
	for (const int &x : s) {
		A[K++] = x;
	}

	for (int i = 0;i < N;i++) {
		for (int j = 0;j < N;j++) {
			M[i][j] = lower_bound(A,A + K,M[i][j]) - A;
			T[i * N + j] = i * N + j;
			P[M[i][j]].push_back(i * N + j);
		}
	}


	for (int i = 0;i < Q;i++) {
		int xa, ya, xb, yb;
		cin >> xa >> ya >> xb >> yb;
		xa--, ya--, yb-- ,xb--;
		if (xa == xb && ya == yb) {
			ans[i] = A[M[xa][ya]];
		} else {
			h[xa * N + ya].insert(i);
			h[xb * N + yb].insert(i);
		}
	}

	for (int i = K - 1;i >= 0;i--) {
		for (const int &p : P[i]) {
			int x = p / N;
			int y = p % N;
			for (int k = 0;k < 4;k++) {
				int xx = x + dx[k];
				int yy = y + dy[k];
				if (xx >= 0 && xx < N && yy >= 0 && yy < N) {
					if (M[xx][yy] >= i) {
						int r1 = getRoot(x * N + y,i);
						int r2 = getRoot(xx * N + yy,i);
						unite(r1,r2,i);
					}
				}
			}
		}
		
	}

	for (int i = 0;i < Q;i++) {
		cout << ans[i] << "\n";
	}
    return 0;
}