Cod sursa(job #2773006)

Utilizator siliviuSilion Liviu siliviu Data 4 septembrie 2021 01:51:39
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.93 kb
#include <bits/stdc++.h>

using namespace std;

int main() {
	ifstream cin("matrice2.in");
	ofstream cout("matrice2.out");
	int n, q, di[] = {1,0,-1,0}, dj[] = {0,1,0,-1};
	cin >> n >> q;
	vector<int> v, ans(q), c(q);
	vector<vector<int>> a(n + 1, vector<int>(n + 1));
	vector<tuple<int, int, int, int>> b(q);
	map<int, int> mp;
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= n; ++j) {
			cin >> a[i][j];
			mp[a[i][j]];
		}
	for (auto& x : b) {
		int x1, y1, x2, y2;
		cin >> x1 >> y1 >> x2 >> y2;
		x = tie(x1, y1, x2, y2);
	}
	int m = 0;
	vector<int> inv = {0};
	for (auto& x : mp) {
		x.second = ++m;
		inv.emplace_back(x.first);
	}
	vector<vector<pair<int, int>>> d(m + 1);
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= n; ++j)
			d[mp[a[i][j]]].emplace_back(i, j);
	for (int i = 1 << (31 - __builtin_clz(m)); i; i >>= 1) {
		vector<vector<int>> e(m + 1);
		for (int j = 0; j < q; ++j)
			if (ans[j] + i <= m) {
				c[j] = ans[j] + i;
				e[c[j]].emplace_back(j);
			}
		vector<int> p(n * n + 1), s(n * n + 1, 1);
		iota(p.begin(), p.end(), 0);
		function<int(int)> get = [&](int a) {
			if (p[a] == a)
				return a;
			return p[a] = get(p[a]);
		};
		auto unite = [&](int a, int b) {
			a = get(a), b = get(b);
			if (a == b) return;
			if (s[b] > s[a])
				swap(a, b);
			p[b] = a;
			s[a] += s[b];
		};
		auto lin = [&](int i, int j) {return (i - 1) * n + j; };
		for (int i = m; i; --i) {
			for (auto x : d[i]) {
				int x1, y1;
				tie(y1, x1) = x;
				for (int k = 0; k < 4; ++k) {
					int y2 = y1 + di[k], x2 = x1 + dj[k];
					if (y2 && x2 && y2 <= n && x2 <= n && a[y2][x2] >= a[y1][x1])
						unite(lin(y1, x1), lin(y2, x2));
				}
			}
			for (auto x : e[i]) {
				int x1, y1, x2, y2;
				tie(y1, x1, y2, x2) = b[x];
				int p1 = lin(y1, x1), p2 = lin(y2, x2);
				if (get(p1) == get(p2))
					ans[x] = c[x];
			}
		}
	}
	for (auto x : ans)
		cout << inv[x] << '\n';
}