Cod sursa(job #1081577)

Utilizator BuseSorinFMI Buse Sorin-Marian BuseSorin Data 13 ianuarie 2014 18:54:40
Problema Matrice 2 Scor 90
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 2.7 kb
#include <stdio.h>
#include <algorithm>
#define Nmax 302
#define Qmax 20002

using namespace std;

struct father{
	int i, j;

	inline bool operator !=(const father &o){
		return (o.i != i || o.j != j);
	}
	inline bool operator ==(const father &o){
		return (o.i == i && o.j == j);
	}
};

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

int N, q;
int X1[Qmax], X2[Qmax], Y1[Qmax], Y2[Qmax];
int Q[Qmax], iq[Qmax], sol[Qmax];
father tt[Nmax][Nmax];
int a[Nmax][Nmax], rg[Nmax][Nmax], b[Nmax][Nmax];
int v[Nmax*Nmax], ind[Nmax*Nmax], X[Nmax*Nmax], Y[Nmax*Nmax];

inline father Find(int i, int j){
	father r, x, w;
	w.i = i; w.j = j;
	for (r = w; r != tt[r.i][r.j];) r = tt[r.i][r.j];

	for (; w != tt[w.i][w.j];){
		x = tt[w.i][w.j];
		tt[w.i][w.j] = r;
		w = x;
	}
	return r;
}

inline void Unite(father f1, father f2){
	if (rg[f1.i][f1.j] > rg[f2.i][f2.j])
		tt[f2.i][f2.j] = f1;
	else tt[f1.i][f1.j] = f2;

	if (rg[f1.i][f1.j] == rg[f2.i][f2.j])
		rg[f2.i][f2.j]++;
}

inline int bun(int x, int y){
	return x>0 && y>0 && x <= N && y <= N && b[x][y];
}
inline int cmp2(int i, int j){
	return Q[i] > Q[j];
}

void search(){
	int step = 1, i, j, v0, ii, k;
	while ((step << 1) <= v[ind[1]]) step <<= 1;
	for (; step; step >>= 1){
		for (i = 1; i <= N; ++i)
		for (j = 1; j <= N; ++j) tt[i][j] = (father){ i, j }, rg[i][j] = 1, b[i][j] = 0;

		for (i = 1; i <= q; ++i){
			Q[i] = sol[i] + step;
			iq[i] = i;
		}
		sort(iq + 1, iq + q + 1, cmp2);

		for (i = 1, j = 1; i <= v[0];){
			for (; j <= q && Q[iq[j]] > v[ind[i]]; ++j)
			if (Find(X1[iq[j]], Y1[iq[j]]) == Find(X2[iq[j]], Y2[iq[j]]))
				sol[iq[j]] += step;

			for (v0 = v[ind[i]]; v[ind[i]] == v0; ++i){
				ii = ind[i]; b[X[ii]][Y[ii]] = 1;
				for (k = 0; k<4; ++k){
					if (bun(X[ii] + dx[k], Y[ii] + dy[k]))
					if (Find(X[ii], Y[ii]) != Find(X[ii] + dx[k], Y[ii] + dy[k]))
						Unite(Find(X[ii], Y[ii]), Find(X[ii] + dx[k], Y[ii] + dy[k]));
				}
			}
		}

		for (; j <= q; ++j)
		if (Find(X1[iq[j]], Y1[iq[j]]) == Find(X2[iq[j]], Y2[iq[j]]))
			sol[iq[j]] += step;
	}
}

inline int cmp(int i, int j){
	return v[i] > v[j];
}

int main(){
	int i, j, x, mx = 0;
	freopen("matrice2.in", "r", stdin);
	freopen("matrice2.out", "w", stdout);
	scanf("%d%d", &N, &q);
	for (i = 1; i <= N; ++i)
	for (j = 1; j <= N; ++j){
		scanf("%d", &x), mx = mx > x ? mx : x;
		a[i][j] = x;
		v[++v[0]] = x;
		X[v[0]] = i; Y[v[0]] = j;
		ind[v[0]] = v[0];
	}
	sort(ind + 1, ind + v[0] + 1, cmp);
	for (i = 1; i <= q; ++i){
		scanf("%d%d%d%d", &X1[i], &Y1[i], &X2[i], &Y2[i]);
		Q[i] = i;
	}

	search();

	for (i = 1; i <= q; ++i) printf("%d\n", sol[i]);
	fclose(stdin); fclose(stdout);
	return 0;
}