Cod sursa(job #397956)

Utilizator katakunaCazacu Alexandru katakuna Data 17 februarie 2010 19:23:23
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.62 kb
#include <cstdio>
#include <algorithm>
using namespace std;

#define Nmax 312
#define Qmax 21110

struct Query {int x1, y1, x2, y2;} Q[Qmax];
struct val {int x, y;} poz[Nmax * Nmax];

int n, T, N, Vmax, sol, nod, fiu;
int a[Nmax][Nmax], Qpoz[Qmax], Sol[Qmax], P[Nmax][Nmax], viz[Nmax * Nmax], Tata[Nmax * Nmax];
int D[2][4] = {{1, 0, -1, 0}, {0, 1, 0, -1}};

void citire ();

int cmp2 (int a, int b) {
	return Sol[a] > Sol[b];
}

int tata (int x) {
	
	while (Tata[x] >= 0)
		x = Tata[x];
	
	return x;
} 

void rezolva () {
	
	int step, val, i, j, l, x, y, t1, t2;
	for (step = 1; step < Vmax; step<<= 1);
	
	for (; step; step>>= 1) {
		// fiecare bit al rezultatului
		memset (viz, 0, sizeof (viz));
		
		sort (Qpoz + 1, Qpoz + T + 1, cmp2);
		
		for (i = 1, j = 1; i <= N;) {
			val = a[poz[i].x][poz[i].y];
			
			//fac queryurile 
			for (; Sol[ Qpoz[j] ] + step > val && j <= T && i != 1; j++) {
				x = P[ Q[ Qpoz[j] ].x1 ][ Q[ Qpoz[j] ].y1 ];
				y = P[ Q[ Qpoz[j] ].x2 ][ Q[ Qpoz[j] ].y2 ];
				
				if (viz[x] && viz[y] && tata (x) == tata (y) ) 
					Sol[ Qpoz[j] ]+= step;
			}
			
			for (; val == a[poz[i].x][poz[i].y]; i++) {
				// adaug nodul cu muchiile corespunzatoare
				nod = P[ poz[i].x ][ poz[i].y ];
				viz[nod] = 1; Tata[nod] = -1;
				
				for (l = 0; l < 4; l++) {
					x = poz[i].x + D[0][l];
					y = poz[i].y + D[1][l];
					fiu = P[x][y];
					
					if (x >= 1 && x <= n && y >= 1 && y <= n && viz[fiu]) {
						t1 = tata (nod);
						t2 = tata (fiu);
						if (t1 != t2) {
							if (-Tata[t1] >= -Tata[t2]) {
								Tata[t1]+= Tata[t2];
								Tata[t2] = t1;
							}
							
							else {
								Tata[t2]+= Tata[t1];
								Tata[t1] = t2;
							}
						}
					}
				}
			}
		}
		
		for (; j <= T && i != 1; j++) 
				if ( tata ( P[ Q[ Qpoz[j] ].x1 ][ Q[ Qpoz[j] ].y1 ] ) == tata ( P[ Q[ Qpoz[j] ].x2 ][ Q[ Qpoz[j] ].y2 ] ) ) 
					Sol[ Qpoz[j] ]+= step;
		
	}
	
	for (i = 1; i <= T; i++)
		printf ("%d\n", Sol[i]);
}

int main () {

	freopen ("matrice2.in", "r", stdin);
	freopen ("matrice2.out", "w", stdout);
	
	citire ();
	rezolva ();
	
	return 0;
}

int cmp (const val &A, const val &B) {
	return a[A.x][A.y] > a[B.x][B.y];
}

void citire () {
	
	int i, j;
	
	scanf ("%d %d", &n, &T);
	for (i = 1; i <= n; i++)
		for (j = 1; j <= n; j++) {
			scanf ("%d", &a[i][j]);
			poz[++N].x = i; poz[N].y = j;
			if (a[i][j] > Vmax) Vmax = a[i][j];
			P[i][j] = N;
		}
	
	for (i = 1; i <= T; i++) {
		scanf ("%d %d %d %d", &Q[i].x1, &Q[i].y1, &Q[i].x2, &Q[i].y2);
		Qpoz[i] = i;
	}
	
	sort (poz + 1, poz + N + 1, cmp);
}