Cod sursa(job #579541)

Utilizator barosanulmarele bastan barosanul Data 12 aprilie 2011 11:15:12
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.58 kb
#include <algorithm>
#include <stdio.h>
#include <vector>

#define MAX 310
#define MAXQ 20010
#define pb push_back
#define mp make_pair
#define x first
#define y second

using namespace std;

int dirX[] = {-1, 0, 0, 1};
int dirY[] = {0, -1, 1, 0};
int n, q;
int matAlt[MAX][MAX];
int xs[MAXQ], ys[MAXQ], xf[MAXQ], yf[MAXQ], sol[MAXQ], loc[MAXQ];
pair <int, int> vctNr[MAX * MAX];
pair <int, int> t[MAX][MAX];
vector <int> vctQuery;

inline bool cmp(const pair <int, int> &a, const pair <int, int> &b)
{
	return matAlt[a.x][a.y] < matAlt[b.x][b.y];
}

inline bool cmpsol(const int &a, const int &b)
{
	return sol[a] < sol[b];
}

inline pair <int, int> tata(pair <int, int> nod)
{
	if (t[nod.x][nod.y] != nod)
		t[nod.x][nod.y] = tata(t[nod.x][nod.y]);

	return t[nod.x][nod.y];
}

inline void cautaBin()
{
	int step = 1;
	for (; step <= 1000000; step *= 2);

	for (; step; step /= 2)
	{
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				t[i][j] = mp(0, 0);

		for (int i = 1; i <= q; i++)
		{
			sol[i] += step;

			loc[i] = i;
		}

		sort(loc + 1, loc + 1 + q, cmpsol);
		reverse(loc + 1, loc + 1 + q);

		int l = 1;
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				t[i][j] = mp(0, 0);
		for (int i = 1; i <= n * n + 1; i++)
		{
			int x = vctNr[i].x, y = vctNr[i].y;

			for (; sol[loc[l]] > matAlt[x][y]; l++)
				if (!(t[xs[loc[l]]][ys[loc[l]]] != mp(0, 0) && t[xf[loc[l]]][yf[loc[l]]] != mp(0, 0) && tata(mp(xs[loc[l]], ys[loc[l]])) == tata(mp(xf[loc[l]], yf[loc[l]]))))
					sol[loc[l]] -= step;
				

			t[x][y] = mp(x, y);

			for (int dir = 0; dir < 4; dir++)
			{
				if (!(x + dirX[dir]) || (x + dirX[dir] > n) || !(y + dirY[dir]) || (y + dirY[dir] > n) || t[x + dirX[dir]][y + dirY[dir]] == mp(0, 0))
					continue;
				pair <int, int> p1 = tata(mp(x, y));
				pair <int, int> p2 = tata(mp(x + dirX[dir], y + dirY[dir]));
			
				if (p1 != p2)
					t[p1.x][p1.y] = tata(mp(p2.x, p2.y));
			}
		}
	}
}

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", &matAlt[i][j]);

			vctNr[(i - 1) * n + j] = mp(i, j);
		}

	sort(vctNr + 1, vctNr + 1 + n * n, cmp);
	reverse(vctNr + 1, vctNr + 1 + n * n);

	for (int i = 1; i <= q; i++)
	{
		scanf("%d %d %d %d", &xs[i], &ys[i], &xf[i], &yf[i]);

		vctQuery.pb(i);
	}
	
	cautaBin();

	for (int i = 1; i <= q; i++)
		printf("%d\n", sol[i]);

	fclose(stdin);
	fclose(stdout);
	return 0;
}