Cod sursa(job #798618)

Utilizator rvnzphrvnzph rvnzph Data 16 octombrie 2012 20:12:12
Problema Matrice 2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.27 kb
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>

#define NLen 0x200
#define QLen 0x8000
#define NumLen 0x100000

using namespace std;

int Mat[NLen][NLen];
int G[NLen][NLen];

int frq[NumLen];
int use[NLen*NLen];
int Sol[QLen];
int aux[QLen];

int N,Q;

struct Point
{
	int sx,sy,fx,fy;
}P[QLen];

struct Position
{
	int val,idx;
}pos[QLen];

inline bool cmp(const Position &a,const Position &b)
{
	return a.val<b.val;
}

const int dx[4]={0,1,0,-1};
const int dy[4]={1,0,-1,0};

inline void fill(int x,int y,int num,int h)
{
	G[x][y]=num;

	for(int i=0;i<4;++i)
		if(0<x+dx[i]&&x+dx[i]<=N&&
		   0<y+dy[i]&&y+dy[i]<=N&&
		   Mat[x+dx[i]][y+dy[i]]>=h&&
		   G[x+dx[i]][y+dy[i]]==0) fill(x+dx[i],y+dy[i],num,h);
}

inline void make_graf(int h)
{
	int cnt=1;

	memset(G,0,sizeof(G));

	for(int i=1;i<=N;++i)
		for(int j=1;j<=N;++j)
			if(G[i][j]==0&&Mat[i][j]>=h)
				{
					fill(i,j,cnt,h);
					++cnt;
				}
}

int main()
{
	freopen("matrice2.in","r",stdin);
	freopen("matrice2.out","w",stdout);

	cin>>N>>Q;

	for(int i=1;i<=N;++i)
		for(int j=1;j<=N;++j)
			cin>>Mat[i][j];

	for(int i=1;i<=Q;++i)
		cin>>P[i].sx>>P[i].sy>>P[i].fx>>P[i].fy;

	//Vector de frecventa
	memset(frq,0,sizeof(frq));
	for(int i=1;i<=N;++i)
		for(int j=1;j<=N;++j)
			frq[Mat[i][j]]=1;

	//Reduc frq, scot elementele de 0
	memset(use,0,sizeof(use));
	for(int i=1;i<NumLen;++i)
		if(frq[i]) use[++use[0]]=i;

	//in Sol tin h max a.i. sa am drum intre (sx,sy) si (fx,fy)
	memset(Sol,0,sizeof(Sol));

	//vector de pozitii pentru fiecare query
	memset(pos,0,sizeof(pos));
	for(int i=1;i<=Q;++i) pos[i].idx=i;
	
	int step;
	for(step=1;step<=use[0];step*=2);
	for(;step;step/=2)
	{
		sort(pos+1,pos+Q+1,cmp);

		memset(aux,0,sizeof(aux));
		for(int i=1;i<=Q;++i)
			if(pos[i].val+step<=use[0])
			{
				if(i==1||pos[i].val!=pos[i-1].val) make_graf(use[pos[i].val+step]);

				if(G[P[pos[i].idx].sx][P[pos[i].idx].sy]==G[P[pos[i].idx].fx][P[pos[i].idx].fy]&&G[P[pos[i].idx].sx][P[pos[i].idx].sy]) aux[i]=pos[i].val+step;
			}

		for(int i=1;i<=Q;++i)
			pos[i].val=aux[i];
	}

	for(int i=1;i<=Q;++i)
		Sol[pos[i].idx]=use[pos[i].val];

	//out
	for(int i=1;i<=Q;++i)
		cout<<Sol[i]<<'\n';

	return 0;
}