Cod sursa(job #1066070)

Utilizator poptibiPop Tiberiu poptibi Data 23 decembrie 2013 23:45:02
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 2.54 kb
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;

#define Nmax 310
#define Qmax 20010

const int DX[4] = {-1, 0, 0, 1};
const int DY[4] = {0, -1, 1, 0};

int N, M, Mat[Nmax][Nmax], A[Nmax][Nmax];
int Father[Nmax * Nmax], AnsQ[Qmax];

struct Cell
{
    int X, Y, Val;
}V[Nmax * Nmax];

struct Query
{
    int X1, Y1, X2, Y2, Ans, Pos;
}Q[Qmax];

struct CmpCells
{
    bool operator() (Cell A, Cell B)
    {
        return A.Val > B.Val;
    }
};

struct CmpQueries
{
    bool operator() (Query A, Query B)
    {
        return A.Ans > B.Ans;
    }
};

int Root(int X)
{
    int Y = X;
    for(; Father[X] != X; X = Father[X]);
    while(Y != X)
    {
        int Aux = Father[Y];
        Father[Y] = X;
        Y = Aux;
    }
    return X;
}

void Merge(int X, int Y)
{
    if(X % 2 == 0) Father[X] = Y;
    else Father[Y] = X;
}

void AddCells(int IdxCell, int MinVal)
{
    int X = V[IdxCell].X, Y = V[IdxCell].Y, k;
    for(k = 0; k < 4; ++ k)
    {
        int NextX = X + DX[k], NextY = Y + DY[k];
        if(1 <= NextX && NextX <= N && 1 <= NextY && NextY <= N && A[NextX][NextY] >= MinVal)
        {
            int RootA = Root(Mat[X][Y]), RootB = Root(Mat[NextX][NextY]);
            if(RootA != RootB) Merge(RootA, RootB);
        }
    }
}

int main()
{
    freopen("matrice2.in", "r", stdin);
    freopen("matrice2.out", "w", stdout);
    int i, j, K = 0;
    scanf("%i %i", &N, &M);
    for(i = 1; i <= N; ++ i)
        for(j = 1; j <= N; ++ j)
        {
            scanf("%i", &A[i][j]);
            V[++K].Val = A[i][j];
            V[K].X = i;
            V[K].Y = j;
            Mat[i][j] = K;
        }

    for(i = 1; i <= M; ++ i) scanf("%i %i %i %i", &Q[i].X1, &Q[i].Y1, &Q[i].X2, &Q[i].Y2), Q[i].Pos = i;

    sort(V + 1, V + N * N + 1, CmpCells());

    int Bit = 0;
    for(; (1 << Bit) <= V[1].Val; Bit ++);
    Bit --;

    for(; Bit >= 0; Bit --)
    {
        for(i = 1; i <= N * N; ++ i) Father[i] = i;
        sort(Q + 1, Q + M + 1, CmpQueries());

        j = 1;
        for(i = 1; i <= M; ++ i)
        {
            int NewAns = Q[i].Ans + (1 << Bit);

            for(; j <= N * N && V[j].Val >= NewAns; ++ j) AddCells(j, NewAns);

            int RootA = Root(Mat[Q[i].X1][Q[i].Y1]), RootB = Root(Mat[Q[i].X2][Q[i].Y2]);
            if(RootA == RootB) Q[i].Ans = NewAns;
        }
    }

    for(i = 1; i <= M; ++ i) AnsQ[Q[i].Pos] = Q[i].Ans;

    for(i = 1; i <= M; ++ i) printf("%i\n", AnsQ[i]);
    return 0;
}