Cod sursa(job #2391369)

Utilizator LucaSeriSeritan Luca LucaSeri Data 28 martie 2019 19:55:46
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.41 kb
#include <bits/stdc++.h>
 
using namespace std;

const int MAXN = 301;

int n = 0;

pair< int, int > t[MAXN][MAXN];
int card[MAXN][MAXN];
int mat[MAXN][MAXN];

struct qqq {
	pair< int, int > a, b;
	qqq(pair< int, int > _a = {0, 0}, pair< int, int > _b = {0, 0}) : a(_a), b(_b) {}
}actual[20010];

pair< int, int > root(pair< int, int > x) {
	if(t[x.first][x.second] == x) return x;
	return t[x.first][x.second] = root(t[x.first][x.second]);
}

void unite(pair< int, int > x, pair< int, int > y) {
	if(card[x.first][x.second] < card[y.first][y.second]) swap(x, y);

	t[y.first][y.second] = x;
	card[x.first][x.second] += card[y.first][y.second];

	return;
}

vector< pair< int, int > > queries;

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};

void unestee(pair< int, int > x) {
	for(int i = 0; i < 4; ++i) {
		pair< int, int > y = x;
		y.first += dx[i];
		y.second += dy[i];

		if(y.first < 0 || y.first >= n || y.second < 0 || y.second >= n) continue;
		if(mat[y.first][y.second] < mat[x.first][x.second]) continue;
		if(root(x) == root(y)) continue;
		unite(root(x), root(y));
	}
}

vector< pair< int, pair< int, int > > > vals;

void add(int val) {
	sort(queries.begin(), queries.end());
	reverse(queries.begin(), queries.end());

	for(int i = 0; i < n; ++i) {
		for(int j = 0; j < n; ++j) {
			t[i][j] = make_pair(i, j);
			card[i][j] = 1;
		}
	}
	int i = 0;
	for(auto &x : queries) {
		while(i < vals.size() && vals[i].first >= x.first + val) {
			unestee(vals[i].second);
			++i;
		}

		if(root(actual[x.second].a) == root(actual[x.second].b)) {
			x.first += val;
		}
	}

	return;
}
int main() {
	#ifdef BLAT
		freopen("input", "r", stdin);
		#define f cin
		#define g cout
	#else
		ifstream f("matrice2.in");
		ofstream g("matrice2.out");
	#endif	

	f >> n;
	int q;
	f >> q;
	for(int i = 0; i < n; ++i) {
		for(int j = 0; j < n; ++j) {
			f >> mat[i][j];
			vals.emplace_back(mat[i][j], make_pair(i, j));
		}
	}

	sort(vals.begin(), vals.end());
	reverse(vals.begin(), vals.end());

	for(int i = 0; i < q; ++i) {
		f >> actual[i].a.first >> actual[i].a.second >> actual[i].b.first >> actual[i].b.second;
		actual[i].a.first--;actual[i].a.second--;actual[i].b.first--;actual[i].b.second--;
		queries.emplace_back(0, i);
	}

	for(int i = 20; i >= 0; --i) add(1<<i);

	sort(queries.begin(), queries.end(), [&](pair< int, int > a, pair< int, int > b) -> bool {return a.second < b.second;});
	
	for(auto &x : queries) g << x.first << '\n';
    return 0;
}