Cod sursa(job #314472)

Utilizator Mishu91Andrei Misarca Mishu91 Data 11 mai 2009 21:55:20
Problema Matrice 2 Scor Ascuns
Compilator cpp Status done
Runda Marime 3.02 kb
using namespace std;
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>

#define NrMax 100000

int N, Q, Pmax, nr;
int A[NrMax], ind[NrMax], T[20][NrMax], TT[NrMax], lvl[NrMax];
char W[NrMax];
vector<int> G[NrMax];
int Qe[NrMax];

int cmp(const int &a, const int &b) { return A[a] > A[b]; }

void citire()
{
 int i, j;
 
 freopen("matrice2.in","r",stdin);
 scanf("%d %d\n",&N,&Q);
 for (i=1; i<=N; ++i)
	 for (j=1; j<=N; ++j)
		 {
		  scanf("%d",&A[++nr]);
		  ind[nr] = TT[nr] = nr;
		 }
}

int tata(int nod)
{
 if (TT[nod] == nod) return TT[nod];
 return TT[nod] = tata(TT[nod]);
}

void disjoint()
{
 int i, nod, t1;
 
 for (i=1; i<=nr; ++i)
	 {
	  nod = ind[i];
	  W[nod] = 1;
	  if ((nod-1)%N && W[nod-1]) 
		  {
			 t1 = tata(nod-1);
			 if (t1!=nod)
				 T[0][t1] = TT[t1] = nod;			 
				 G[nod].push_back(t1);
		  }
	  if (nod>N && W[nod-N])
		  {
			 t1 = tata(nod-N);
			 if (t1!=nod)
				 T[0][t1] = TT[t1] = nod,
				 G[nod].push_back(t1);
		  }
	  if (nod%N && W[nod+1])
		  {
			 t1 = tata(nod+1);
			 if (t1!=nod)
				 T[0][t1] = TT[t1] = nod,
				 G[nod].push_back(t1);
		  }
	  if (nod+N<=nr && W[nod+N])
		  {
			 t1 = tata(nod+N);
			 if (t1!=nod)
				 T[0][t1] = TT[t1] = nod,
				 G[nod].push_back(t1);
		  }
	 }
}

void stramosi()
{
 int p, i;
 for (p=1; (1<<p)<=nr; ++p)
	 for (i=1; i<=nr; ++i)
		 T[p][i] = T[p-1][T[p-1][i]];
 Pmax = p;
}

void dfs(int nod)
{
 vector<int>::iterator it;
 lvl[nod] = lvl[T[0][nod]] + 1;
 for (it=G[nod].begin(); it<G[nod].end(); ++it)	
		 dfs(*it);
}

int lca(int a, int b)
{
 int aux, p, nod;
 //vino pe acelasi nivel
 if (lvl[a]<lvl[b]) { aux=a; a=b; b=aux; }
 nod = a;
 p = Pmax;
 while (p)
	 {
		if (lvl[T[p-1][nod]] >= lvl[b]) nod=T[p-1][nod];
		--p;		
	 }
 a = nod;
 //gaseste lca
 p = Pmax;
 while (p)
	 {
		if (T[p-1][a] != T[p-1][b])
			a=T[p-1][a],
			b=T[p-1][b];
		--p;
	 }
 if (a!=b) a=T[0][a];
 return a;
}

void brut_force(int a, int b)
{
 int p = 1, st, dr, nod, rez = nr;
 while (p<=nr) p<<=1;
 p>>=1;
 
 while (p)
	 {
		memset(W, 0, sizeof(W));
		Qe[st=dr=0] = a;
		//printf("  %d\n",A[ind[rez-p]]);
		while (st<=dr)
			{
			 nod = Qe[st];
			 ++st;
			 if (A[nod] < A[ind[rez-p]]) continue;
			 if ((nod-1)%N && !W[nod-1]) W[ Qe[++dr] = nod-1 ] = 1;
			 if (nod>N && !W[nod-N]) W[ Qe[++dr] = nod - N ] = 1;
			 if (nod%N && !W[nod+1]) W[ Qe[++dr] = nod + 1 ] = 1;
			 if (nod+N <= nr && !W[nod+N]) W[ Qe[++dr] = nod+N ] = 1;
			}
	  if (W[b] && A[b] >= A[ind[rez-p]]) rez-=p;
	  p>>=1;
	  while (rez-p<=0) p>>=1;
	 }

 printf("%d\n",A[ind[rez]]);
}

int main()
{
 int i, x1, y1, x2, y2;
 
 citire();
 
 sort(ind+1, ind+nr+1, cmp);
 disjoint();
 
 stramosi();

 dfs( ind[nr] );
 
 freopen("matrice2.out","w",stdout);
 for (i=0; i<Q; ++i)
	 {
		scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
		printf("%d\n", A[ lca((x1-1)*N+y1, (x2-1)*N+y2) ] );			
		//brut_force((x1-1)*N+y1, (x2-1)*N+y2);
	 }
 
 fclose(stdout);
 return 0;
}