Cod sursa(job #332125)

Utilizator AndreyPAndrei Poenaru AndreyP Data 16 iulie 2009 18:10:48
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
#include<stdio.h>
#include<bitset>
#include<algorithm>
using namespace std;
#define N 310
#define Q 20010
#define NR 90010
#define fs first
#define sc second
#define mp make_pair
#define pii pair<int,int>
int n,q;
int c[NR],nr,ind[NR],ind2[Q],pc[N][N];
int t[NR],deg[NR];
int sol[Q],query[Q];
const int dx[]={-1,0,1,0};
const int dy[]={0,1,0,-1};
pii h[NR],p[Q];
bitset<N> a[N];
bool compar(const int &x,const int &y)
{
	if(c[x]>c[y])
		return true;
	return false;
}
bool compar2(const int &x,const int &y)
{
	if(query[x]>query[y])
		return true;
	return false;
}
inline void citire()
{
	scanf("%d%d",&n,&q);
	for(int i=1; i<=n; ++i)
	{
		for(int j=1; j<=n; ++j)
		{
			++nr;
			scanf("%d",&c[nr]);
			h[nr]=mp(i,j);
                        ind[nr]=nr;
			pc[i][j]=nr;
		}
	}
	int a,b,c,d;
	for(int i=1; i<=q; ++i)
	{
		scanf("%d%d%d%d",&a,&b,&c,&d);
		p[i]=mp(pc[a][b],pc[c][d]);
		ind2[i]=i;
	}
	sort(ind+1,ind+nr+1,compar);
}
inline int find(int x)
{
	int r=x;
	for(; t[r]!=r; r=t[r])
		;
	while(x!=r)
	{
		int aux=t[x];
		t[x]=r;
		x=aux;
	}
	return r;
}
inline void unesc(int x,int y)
{
        x=find(x);
	y=find(y);
	if(deg[x]<deg[y])
		t[x]=y;
	else
		t[y]=x;
	if(deg[x]==deg[y])
		++deg[x];
}
int main()
{
	freopen("matrice2.in","r",stdin);
	freopen("matrice2.out","w",stdout);
        citire();
     	int step=1;
	for(; step<c[ind[1]]; step<<=1)
		;
	if(step!=c[ind[1]])
		step>>=1;
	for(; step; step>>=1)
	{
		int i,j;
		for(i=1; i<=q; ++i)
			query[i]=sol[i]+step;
                sort(ind2+1,ind2+q+1,compar2);
		for(i=1; i<=nr; ++i)
		{
			t[i]=i;
			deg[i]=1;
		}
		for(i=1; i<=n; ++i)
			a[i].reset();
                for(i=1,j=1; i<=nr && j<=q;)
		{
			for(; j<=q && query[ind2[j]]>c[ind[i]]; ++j)
			{
				if(find(p[ind2[j]].fs)==find(p[ind2[j]].sc))
					sol[ind2[j]]=query[ind2[j]];
			}
			for(int k=i; i<=nr && c[ind[k]]==c[ind[i]]; ++i)
			{
				int x=h[ind[i]].fs;
				int y=h[ind[i]].sc;
				a[x][y]=1;
				for(int w=0; w<4; ++w)
				{
					int x1=x+dx[w];
					int y1=y+dy[w];
					if(x1>0 && y1>0 && x1<=n && y1<=n && a[x1][y1]==1)
						unesc(ind[i],pc[x1][y1]);
				}
			}
		}
		for(; j<=q; ++j)
		{
			if(find(p[ind2[j]].fs)==find(p[ind2[j]].sc))
				sol[ind2[j]]=query[ind2[j]];
		}
	}
	for(int i=1; i<=q; ++i)
		printf("%d\n",sol[i]);
	return 0;
}