Cod sursa(job #2919782)

Utilizator tryharderulbrebenel mihnea stefan tryharderul Data 19 august 2022 17:45:19
Problema Matrice 2 Scor 95
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.46 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 303;
const int QMAX = 20003;

int n, q;
int v[NMAX][NMAX], Start[QMAX], End[QMAX], ans[QMAX], ind[QMAX], ax[QMAX], ay[QMAX];
bool used[NMAX * NMAX], answered[QMAX];
pair<int, int> a[NMAX * NMAX];
vector<int> g[NMAX*NMAX];

int cod(int i, int j) {
	return n * (i-1) + j;
}

class DSU {
private:
	int t[NMAX * NMAX];
public:
	DSU() {
		for(int i = 1; i <= NMAX * NMAX; i++)
			t[i] = i;
	}
	int Find(int node) {
		int root = node;
		while(root != t[root]) {
			root = t[root];
		}
		while(node != t[node]) {
			int aux = t[node];
			t[node] = root;
			node = aux;
		}
		return root;
	}
	void unite(int x, int y) {
		x = Find(x);
		y = Find(y);
		if(x == y) return ;
		t[x] = y;
	}
	void clear() {
		for(int i = 1; i <= NMAX * NMAX; i++)
			t[i] = i, used[i] = 0;
	}
}ds;

void add_edge(int x, int y) {
	g[x].push_back(y);
	g[y].push_back(x);
}

void add_node(int node) {
	for(int son : g[node]) 
		if(used[son])
			ds.unite(node, son);
	used[node] = 1;
}

int main() {
	freopen("matrice2.in","r",stdin);
	freopen("matrice2.out","w",stdout);
	scanf("%d %d", &n, &q);
	for(int i = 1; i <= n; i++) 
		for(int j = 1; j <= n; j++) {
			scanf("%d", &v[i][j]);
			a[cod(i, j)].first = v[i][j];
			a[cod(i, j)].second = cod(i, j);
		}

	int nr = n*n;
	sort(a+1, a+nr+1);
	reverse(a+1, a+nr+1);

	for(int i = 1; i <= n; i++) 
		for(int j = 1; j <= n; j++) {
			if(i < n)
				add_edge(cod(i, j), cod(i+1, j));
			if(j < n)
				add_edge(cod(i, j), cod(i, j+1));
		}
	
	for(int i = 1; i <= q; i++) {
		int a, b, x, y;
		scanf("%d %d %d %d", &a, &b, &x, &y);
		Start[i] = cod(a, b);
		End[i] = cod(x, y);
		ind[i] = i;
	}
	
	for(int p = 19; p >= 0; p--) {
		ds.clear();
		int add = 1<<p, idx = 1;
		for(int i = 1; i <= q; i++) {
			while(idx <= nr && a[idx].first >= ans[ind[i]] + add)
				add_node(a[idx++].second);
				
			if(ds.Find(Start[ind[i]]) == ds.Find(End[ind[i]]))
				ans[ind[i]] += add, answered[i] = 1;
			else
				answered[i] = 0;
		}
		
		int lx = 0, ly = 0, py = 1, cnt = 0;
		for(int i = 1; i <= q; i++) {
			if(answered[i])
				ax[++lx] = ind[i];
			else
				ay[++ly] = ind[i];
		}

		for(int i = 1; i <= lx; i++) {
			while(py <= ly && ans[ay[py]] >= ans[ax[i]])
				ind[++cnt] = ay[py++];
			ind[++cnt] = ax[i];
		}
		while(py <= ly)
			ind[++cnt] = ay[py++];

		////printf("%d: ", add);
		////for(int i = 1; i <= q; i++)
			////printf("%d ", ind[i]);
		////printf("\n");
	}
	
	for(int i = 1; i <= q; i++)
		printf("%d\n", ans[i]); 
	
	return 0;
}