Cod sursa(job #2545444)

Utilizator alex2209alexPavel Alexandru alex2209alex Data 13 februarie 2020 09:08:21
Problema Matrice 2 Scor 35
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.39 kb
#include <bits/stdc++.h>
 
using namespace std;
ifstream f("matrice2.in");
ofstream g("matrice2.out");
//---------------------------
///Globale
int n,m,v[301][301],rasp[20001],rad[301][301],el[301][301],linii[90001],coloane[90001];
struct str
{
	int x,y,x2,y2,poz;
}query[20001];
//---------------------------
///Functii
void citire();
void cauta_binar_in_paralel(int,int,int,int);
void afisare();
//---------------------------
int main()
{
	citire();
	cauta_binar_in_paralel(1,m,1,1000001);
	afisare();
	return 0;
}
//---------------------------
void afisare()
{
	for(int i = 1; i <= m; ++i)
		g << rasp[i] << '\n';
}
//---------------------------
bool cauta(int l,int c,int l2,int c2)
{
	int x = l;
	int y = c;
	while(linii[rad[x][y]] != x or coloane[rad[x][y]] != y)
	{
		int a = linii[rad[x][y]];
	    int b = coloane[rad[x][y]];
		x = a;
		y = b;
	}
	int x2 = l2;
	int y2 = c2;
	while(linii[rad[x2][y2]] != x2 or coloane[rad[x2][y2]] != y2)
	{
		int a = linii[rad[x2][y2]];
	    int b = coloane[rad[x2][y2]];
		x2 = a;
		y2 = b;
	}
	while(l != x or c != y)
	{
		int aux = rad[l][c];
		rad[l][c] = rad[x][y];
		l = linii[aux];
		c = coloane[aux];
	}
	while(l2 != x2 or c2 != y2)
	{
		int aux = rad[l2][c2];
		rad[l2][c2] = rad[x2][y2];
		l2 = linii[aux];
		c2 = coloane[aux];
	}
	if(x == x2 && y == y2)
		return 1;
	return 0;
}
//---------------------------
void uneste(int l,int c,int l2,int c2)
{
	int x = l;
	int y = c;
	while(linii[rad[x][y]] != x or coloane[rad[x][y]] != y)
	{
	    int a = linii[rad[x][y]];
	    int b = coloane[rad[x][y]];
		x = a;
		y = b;
	}
	int x2 = l2;
	int y2 = c2;
	while(linii[rad[x2][y2]] != x2 or coloane[rad[x2][y2]] != y2)
	{
	    int a = linii[rad[x2][y2]];
	    int b = coloane[rad[x2][y2]];
		x2 = a;
		y2 = b;
	}
	if(el[x][y] < el[x2][y2])
	{
		swap(l,l2);
		swap(c,c2);
		swap(x,x2);
		swap(y,y2);
	}
	if(x != x2 or y != y2)
	{
		el[x][y] += el[x2][y2];
		rad[x2][y2] = rad[x][y];
	}
	while(l != x or c != y)
	{
		int aux = rad[l][c];
		rad[l][c] = rad[x][y];
		l = linii[aux];
		c = coloane[aux];
	}
	while(l2 != x or c2 != y)
	{
		int aux = rad[l2][c2];
		rad[l2][c2] = rad[x][y];
		l2 = linii[aux];
		c2 = coloane[aux];
	}
}
//---------------------------
void cauta_binar_in_paralel(int in,int sf,int st,int dr)
{
	if(dr < st or sf < in)
		return;
	queue<str>q,q2;
	int nr = 0;
	int mij = (st + dr) / 2;
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= n; ++j)
		{
			if(v[i][j] >= mij)
			{
				rad[i][j] = ++nr;
				el[i][j] = 1;
				linii[nr] = i;
				coloane[nr] = j;
			}
			if(v[i][j] >= mij && v[i - 1][j] >= mij)
				uneste(i,j,i - 1,j);
			if(v[i][j] >= mij && v[i][j - 1] >= mij)
				uneste(i,j,i,j - 1);
		}
	for(int i = in; i <= sf; ++i)
	{
		int l = query[i].x;
		int c = query[i].y;
		int l2 = query[i].x2;
		int c2 = query[i].y2;
		if(v[l][c] >= mij && v[l2][c2] >= mij && cauta(l,c,l2,c2))
			q.push(query[i]);
		else
			q2.push(query[i]);
	}
	nr = in;
	while(!q2.empty())
	{
		query[nr] = q2.front();
		q2.pop();
		nr++;
	}
	int nr2 = nr;
	while(!q.empty())
	{
		query[nr2] = q.front();
		rasp[query[nr2].poz] = mij;
		q.pop();
		nr2++;
	}
	cauta_binar_in_paralel(in,nr - 1,st,mij - 1);
	cauta_binar_in_paralel(nr,sf,mij + 1,dr);
}
//---------------------------
void citire()
{
	f >> n >> m;
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= n; ++j)
			f >> v[i][j];
	for(int i = 1; i <= m; ++i)
	{
		f >> query[i].x >> query[i].y >> query[i].x2 >> query[i].y2;
		query[i].poz = i;
		rasp[i] = 1;
	}
}