Cod sursa(job #1582491)

Utilizator TimitocArdelean Andrei Timotei Timitoc Data 27 ianuarie 2016 22:52:16
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.59 kb
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <vector>
#define MAXN 350
#define MAXQ 20050
#define MAXVAL 1000050

using namespace std;

int n, q, a[MAXN][MAXN];
struct query
{
    int x1, y1, x2, y2;
    query(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0) : x1(x1), y1(y1), x2(x2), y2(y2) { }
};
struct elem
{
    int x, y, val;
    elem(int x = 0, int y = 0, int val = 0) : x(x), y(y), val(val) { }
    bool operator()(elem e, elem f)
    {
        return e.val > f.val;
    }
};
query stion[MAXQ];
int state[MAXQ], trial[MAXQ], ind[MAXQ];
elem mat1d[MAXN*MAXN], parent[MAXN][MAXN];

void citire()
{
	scanf("%d %d", &n, &q);
    for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			scanf("%d", &a[i][j]);
	for (int i = 1; i <= q; i++)
		scanf("%d %d %d %d", &stion[i].x1, &stion[i].y1, &stion[i].x2, &stion[i].y2);
    for (int i = 1, k = 0; i <= n; i++)
		for (int j = 1; j <= n; j++)
			mat1d[++k] = elem(i, j, a[i][j]);
    sort(mat1d+1, mat1d+1+n*n, elem());
}

bool cmp(int i, int j)
{
	return trial[i] > trial[j];
}

elem getParent(int x, int y)
{
    if (parent[x][y].x == x && parent[x][y].y == y)
		return parent[x][y];
    else
		return parent[x][y] = getParent(parent[x][y].x, parent[x][y].y);
}

void unify(int x1, int y1, int x2, int y2)
{
	elem g = getParent(x1, y1);
    parent[g.x][g.y] = getParent(x2, y2);
}

void percolate(elem e)
{
	int dx[4] = {-1, 0, 1, 0};
	int dy[4] = {0, 1, 0, -1};
    for (int i = 0; i < 4; i++) {
        int nx = e.x + dx[i];
        int ny = e.y + dy[i];
        if (nx >= 1 && nx <= n && ny >= 1 && ny <= n && a[nx][ny] >= a[e.x][e.y])
            unify(e.x, e.y, nx, ny);
    }
}

int united(query s)
{
	elem e = getParent(s.x1, s.y1);
	elem f = getParent(s.x2, s.y2);
    return  e.x == f.x && e.y == f.y;
}

void ssq()
{
	for (int i = 1; i <= q; i++)
		ind[i] = i;
	sort(ind+1, ind+q+1, cmp);
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			parent[i][j] = elem(i, j, 0);
    for (int i = 1, j = 1; i <= q; i++) {
		int minVal = trial[ind[i]];
        for (j; j <= n*n && mat1d[j].val >= minVal; j++)
			percolate(mat1d[j]);
		if (united(stion[ind[i]]))
			state[ind[i]] = trial[ind[i]];
    }
}

void solve()
{
    int step = 1;
    for (step; (step<<1) <= MAXVAL; step <<= 1);
    for (step; step; step >>= 1) {
		for (int i = 1; i <= q; i++)
			trial[i] = state[i] + step;
        ssq();
    }
}

void afisare()
{
    for (int i = 1; i <= q; i++)
		printf("%d\n", state[i]);
}

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

    citire();
    solve();
    afisare();

    return 0;
}