Cod sursa(job #677034)

Utilizator eudanipEugenie Daniel Posdarascu eudanip Data 9 februarie 2012 20:04:22
Problema Matrice 2 Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.34 kb
#include<stdio.h>
#include<algorithm>
using namespace std;

#define pi pair<int,int>
#define pii pair< pi , int>
#define piii pair< pair< pi,pi > ,int>
#define mp make_pair
#define f first
#define s second
#define x f.f
#define y f.s
#define z second
#define px1 f.f.f
#define py1 f.f.s
#define px2 f.s.f
#define py2 f.s.s
#define NMAX 305
#define NNMAX 90005
#define QMAX 20005

pi b[NNMAX];
pi tata[NMAX][NMAX];
pii event[NNMAX],newevent[NNMAX];
int grad[NMAX][NMAX],a[NMAX][NMAX];
int sol[QMAX],nr,newnr,n,m,nr0,nr1;
piii q[QMAX],vect0[QMAX],vect1[QMAX];
char g[NMAX][NMAX],viz[NNMAX];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};

pi find(pi a)
{
	if(tata[a.f][a.s]==a)
		return a;
	tata[a.f][a.s]=find(tata[a.f][a.s]);	
	return tata[a.f][a.s];
}

void baga(pi p)
{	
	int sx,sy;
	
	g[p.f][p.s]=1;
	for(int i=0;i<4;i++)
	{
		sx=p.f+dx[i];
		sy=p.s+dy[i];
		if(sx<1 || sx>n || sy<1 || sy>n || !g[sx][sy])
			continue;
		pi t1=find(mp(p.f,p.s));			
		pi t2=find(mp(sx,sy));
		if(t1==t2)
			continue;
		if(grad[t1.f][t1.s]>grad[t2.f][t2.s])	
		{
			tata[t2.f][t2.s]=t1;
			grad[t1.f][t1.s]+=grad[t2.f][t2.s];
		}
		else
		{
			tata[t1.f][t1.s]=t2;
			grad[t2.f][t2.s]+=grad[t1.f][t1.s];
		}
	}
}

int verifica(int pq)
{
	pi t1=find(mp(q[pq].px1,q[pq].py1));
	pi t2=find(mp(q[pq].px2,q[pq].py2));
	return t1==t2;
}

inline int cmp(const pi& p1,const pi& p2)
{
	return a[p1.f][p1.s]>a[p2.f][p2.s];
}

int main ()
{
	int i,j,last,stop=0;
	
	freopen("matrice2.in","r",stdin);
	freopen("matrice2.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			scanf("%d",&a[i][j]);
	for(i=1;i<=m;i++)
	{
		scanf("%d%d%d%d",&q[i].px1,&q[i].py1,&q[i].px2,&q[i].py2);
		q[i].z=i;
	}	
	for(i=1;i<=n;i++)	
		for(j=1;j<=n;j++)
			b[(i-1)*n+j]=mp(i,j);
	sort(b+1,b+n*n+1,cmp);		
	event[0].z=0;
	event[2].z=n*n+1;	
	event[nr=1]=mp(mp(1,m),(n*n+1)/2);	
	while(!stop)	
	{
	//	printf("Am un nou nr=%d\n",nr);
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
			{
				tata[i][j]=mp(i,j);
				grad[i][j]=1;
				g[i][j]=0;
			}	
		newnr=0;
		last=0;
		stop=1;
		for(i=1;i<=nr;i++)
		{
			if(viz[event[i].z])
			{
				newevent[++newnr]=event[i];
				continue;
			}	
			stop=0;
			//printf("Calculez pt %d mai exact pt valoare %d\n",event[i].z,a[b[event[i].z].f][b[event[i].z].s]);	
			viz[event[i].z]=1;	
			for(j=last+1;j<=event[i].z;j++)
			{
				baga(b[j]);
			//	if(event[i].z==9)
			//		printf("Am bagat elementul %d %d cu valoarea %d\n",b[j].f,b[j].s,a[b[j].f][b[j].s]);
			}	
			last=event[i].z;
			nr0=0;
			nr1=0;
			for(j=event[i].x;j<=event[i].y;j++)	
				if(verifica(j))
				{
					vect1[++nr1]=q[j];
					//printf("Cel deal %d-lea query a trecut\n",q[j].z);
				}	
				else
				{
					//printf("%d nu a trecut\n",q[j].z);
					vect0[++nr0]=q[j];
				}	
			for(j=event[i].y-nr1+1;j<=event[i].y;j++)				
				sol[q[j].z]=a[b[event[i].z].f][b[event[i].z].s];		
			if(nr1)
			{
				for(j=event[i].y-nr1+1;j<=event[i].y;j++)
					q[j]=vect1[j-event[i].y+nr1];
				newevent[++newnr]=mp(mp(event[i].y-nr1+1,event[i].y),(event[i].z+event[i-1].z)/2);		
			}	
			newevent[++newnr]=event[i];
			if(nr0)
			{
				for(j=event[i].x;j<=event[i].x+nr0-1;j++)		
					q[j]=vect0[j-event[i].x+1];
				newevent[++newnr]=mp(mp(event[i].x,event[i].x+nr0-1),(event[i+1].z+event[i].z)/2);
			}
		}	
		for(i=1;i<=newnr;i++)
			event[i]=newevent[i];
		nr=newnr;
		event[nr+1].z=n*n+1;	
	}
	for(i=1;i<=m;i++)
		printf("%d\n",sol[i]);
	return 0;
}