Cod sursa(job #370396)

Utilizator victor.ionescuIonescu Victor Cristian victor.ionescu Data 1 decembrie 2009 00:24:17
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.9 kb
#include <fstream>
#include <algorithm>
#include <cstring>
#define MAX 310
#define MAXQ 20010
using namespace std;
ifstream fi("matrice2.in");
ofstream fo("matrice2.out");
struct query{int x,y,st,dr,no,rasp;} vQ[MAXQ];
int P[MAX*MAX],W[MAX*MAX];
struct elem{ int val,nr; } v[MAX*MAX];
int sol[MAXQ],N,Q;

inline bool cmpE(const elem &A,const elem &B){
	return (A.val<B.val);
}
inline bool cmpQ(const query &A, const query &B){
	if (A.st>A.dr) return false;
	if (B.st>B.dr) return true;
	return ((A.st+A.dr)/2)<((B.st+B.dr)/2);
}

int find_set(int x){
	if (x!=P[x]) P[x]=find_set(P[x]);
	return P[x];
}

void join(int x,int y){
	int X=find_set(x),Y=find_set(y);
	if (X!=Y)
		if (W[X]<W[Y]) P[X]=Y; else 
			if (W[X]>W[Y]) P[Y]=X; else {
				P[X]=Y;
				++W[Y];
			}
}

int main(){
	fi>>N>>Q;
	int nr=0,x,y,x1,y1,cQ=Q;
	for (int i=1;i<=N;++i)
		for (int j=1;j<=N;++j){
			fi>>x;
			++nr;
			v[nr].val=x;v[nr].nr=nr;
		}
	for (int i=1;i<=Q;++i){
		fi>>x>>y>>x1>>y1;
		vQ[i].x=(x-1)*N+y;
		vQ[i].y=(x1-1)*N+y1;
		vQ[i].st=1;
		vQ[i].dr=N*N;
		vQ[i].rasp=0;
		vQ[i].no=i;
	}
	sort(v+1,v+N*N+1,cmpE);
	do {
		sort(vQ+1,vQ+Q+1,cmpQ);
		while (Q>0 && vQ[Q].st>vQ[Q].dr) --Q;
		memset(P,0,sizeof(P));
		memset(W,0,sizeof(W));
		int ind=N*N+1;
		for (int i=Q;i>=1;--i){
			int target=(vQ[i].st+vQ[i].dr)/2;
			while (ind>target){
				--ind;
				P[v[ind].nr]=v[ind].nr;
				if (v[ind].nr>N && P[v[ind].nr-N]) join(v[ind].nr,v[ind].nr-N);
				if ((v[ind].nr+N)<=N*N && P[v[ind].nr+N]) join(v[ind].nr,v[ind].nr+N);
				if (v[ind].nr%N!=1 && P[v[ind].nr-1]) join(v[ind].nr,v[ind].nr-1);
				if (v[ind].nr%N!=0 && P[v[ind].nr+1]) join(v[ind].nr,v[ind].nr+1);
			}
			int X=find_set(vQ[i].x),Y=find_set(vQ[i].y);
			if (X==0 || Y==0 || X!=Y) vQ[i].dr=target-1; else { vQ[i].rasp=target;vQ[i].st=target+1; }
		}
	} while (Q);
	for (int i=1;i<=cQ;++i) sol[vQ[i].no]=v[vQ[i].rasp].val;
	for (int i=1;i<=cQ;++i) fo<<sol[i]<<"\n";
	fi.close();fo.close();
	return 0;
}