Cod sursa(job #1994253)

Utilizator GabiTulbaGabi Tulba-Lecu GabiTulba Data 24 iunie 2017 14:45:53
Problema Matrice 2 Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.21 kb
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>

#define INF 2140000000
#define MaxN 305
#define MaxQ 200000
#define pi 3.1415926535897932384626433832795

using namespace std;

FILE *IN,*OUT;

int N,Q,Last[MaxQ],Max=0,pos=0;
struct spec
{
	int fx,fy,value;
}Mat[MaxN][MaxN];
struct spec2
{
	int value,x,y;
}l[MaxN*MaxN];
struct query
{
	int x1,y1,x2,y2,pos;
};
vector <query> Quest;
bool cond(spec2 a,spec2 b)
{
	return a.value>b.value;
}
queue <pair<pair<int,int>,vector<query> > > Queue;
void Reinitialize()
{
	pos=0;
	for(int i=1;i<=N;i++)	
		for(int j=1;j<=N;j++)
			Mat[i][j].fx=i,Mat[i][j].fy=j;
}
pair<int,int>find(int x,int y)
{
	pair<int,int>orig;
	orig.first=x,orig.second=y;
	while(Mat[x][y].fx!=x||Mat[x][y].fy!=y)
	{
		int ax=Mat[x][y].fx,ay=Mat[x][y].fy;
		x=ax,y=ay;
	}
	while(orig.first!=x||orig.second!=y)
	{
		int ax=Mat[orig.first][orig.second].fx,ay=Mat[orig.first][orig.second].fy;
		Mat[orig.first][orig.second].fx=x;
		Mat[orig.first][orig.second].fy=y;
		orig.first=ax,orig.second=ay;
	}
	return make_pair(x,y);
}
void Add(spec2 point)
{
	int X=point.x,Y=point.y,V=point.value;
	if(Mat[X][Y].fx!=X||Mat[X][Y].fy!=Y)
		return;
	if(X>1&&Mat[X-1][Y].value>=V)
	{
		pair<int,int> f=find(X-1,Y);
		Mat[f.first][f.second].fx=X;
		Mat[f.first][f.second].fy=Y;
	}
	if(Y>1&&Mat[X][Y-1].value>=V)
	{
		pair<int,int> f=find(X,Y-1);
		Mat[f.first][f.second].fx=X;
		Mat[f.first][f.second].fy=Y;
	}
	if(X<N&&Mat[X+1][Y].value>=V)
	{
		pair<int,int> f=find(X+1,Y);
		Mat[f.first][f.second].fx=X;
		Mat[f.first][f.second].fy=Y;
	}
	if(Y<N&&Mat[X][Y+1].value>=V)
	{
		pair<int,int> f=find(X,Y+1);
		Mat[f.first][f.second].fx=X;
		Mat[f.first][f.second].fy=Y;
	}
}
int main() {

	IN=fopen("matrice2.in","r");
	OUT=fopen("matrice2.out","w");

	fscanf(IN,"%d%d",&N,&Q);

	for(int i=1;i<=N;i++)
		for(int j=1;j<=N;j++)
		{
			fscanf(IN,"%d",&Mat[i][j].value);
			Mat[i][j].fx=i;
			Mat[i][j].fy=j;
			l[(i-1)*N+j].value=Mat[i][j].value;
			l[(i-1)*N+j].x=i;
			l[(i-1)*N+j].y=j;
			Max=max(Max,Mat[i][j].value);
		}
	sort(l+1,l+1+N*N,cond);
	for(int i=1;i<=Q;i++)
	{
		query aux;
		fscanf(IN,"%d%d%d%d",&aux.x1,&aux.y1,&aux.x2,&aux.y2);
		aux.pos=i;
		Quest.push_back(aux);	
	}
	l[0].value=INF;
	Queue.push(make_pair(make_pair(Max,0),Quest));
	while(!Queue.empty())
	{
		int L=Queue.front().first.first;
		int R=Queue.front().first.second;
		int Mid=(R+L)>>1;
		vector<query> left,right;
		if(l[pos].value<Mid)
			Reinitialize();
		while(l[pos+1].value>Mid)
			Add(l[++pos]);
		for(int i=0;i<Queue.front().second.size();i++)
		{
			query aux=Queue.front().second[i];
			if(find(aux.x1,aux.y1)==find(aux.x2,aux.y2))
				left.push_back(aux);
			else right.push_back(aux);
		}
		if(L-R==1)
		{
			for(int i=0;i<left.size();i++)
				Last[left[i].pos]=L;
			for(int i=0;i<right.size();i++)
				Last[right[i].pos]=R;
		}
		else
		{
			if(!left.empty())
				Queue.push(make_pair(make_pair(L,Mid+1),left));
			if(!right.empty())
				Queue.push(make_pair(make_pair(Mid,R),right));
		}
		Queue.pop();
	}
	for(int i=1;i<=Q;i++)
		fprintf(OUT,"%d\n",Last[i]);
    return 0;
}