Cod sursa(job #572767)

Utilizator AndrewTheGreatAndrei Alexandrescu AndrewTheGreat Data 5 aprilie 2011 16:48:45
Problema Matrice 2 Scor 95
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.33 kb
#include <stdio.h>
#include <algorithm>
#include <vector>
#define pb push_back
#define TR(C, i)\
    for(i = C.begin(); i != C.end(); i++)


using namespace std;
const int nmax = 310;
const int Qmax = 20010;
int V[nmax * nmax], M[nmax][nmax], sir[nmax * nmax], Done[Qmax];
int N, Quest, unde, TT[nmax * nmax], RG[nmax * nmax], QU[Qmax];

struct cmp
{
    bool operator()(const int &a, const int &b)const
    {
        return V[a] < V[b];
    }
};

struct pct
{
    int x, y;
};
pct P[nmax * nmax], Q[Qmax][2];


void read()
{
    unde = 0;
    freopen ("matrice2.in", "r", stdin);
    freopen ("matrice2.out", "w", stdout);

    scanf("%d %d", &N, &Quest);
    int i, j;
    for(i = 1; i <= N; i++)
        for(j = 1; j <= N; j++)
        {
            scanf("%d", &V[++unde]);
            sir[unde] = unde;
            M[i][j] = unde;
            P[unde].x = i;
            P[unde].y = j;
            RG[unde] = 1;
            TT[unde] = unde;
        }

    sort(sir + 1, sir + 1 + N * N, cmp());

    for(i = 1; i <= Quest; i++)
        scanf("%d %d %d %d", &Q[i][0].x, &Q[i][0].y, &Q[i][1].x, &Q[i][1].y);
}

vector<int> L;
int Viz[nmax][nmax];
int di[4] = {-1, 0, 0, 1},
    dj[4] = { 0,-1, 1, 0};

int find(int a)
{
    int R, t = a;
    while(a != TT[a])
        a = TT[a];

    while(t != TT[t])
    {
        R = TT[t];
        TT[t] = a;
        t = R;
    }
    return a;
}

void Unite(int a, int b)
{
    if(RG[a] > RG[b])
        TT[b] = a;
    else TT[a] = b;

    if(RG[a] == RG[b])
        RG[b]++;
}

struct cmp2
{
    bool operator()(const int &a, const int &b)const
    {
        return QU[a] > QU[b];
    }
};

int Sol[Qmax], P2[Qmax];

void solve()
{
    int step, i, j, p, k, cx, cy;
    for(step = 1; step <= unde; step <<= 1);
    step >>= 1;
    while(step)
    {
        for(i = 1; i <= Quest; i++)
        {
            QU[i] = Sol[i] + step;
            P2[i] = i;
        }

        sort(P2 + 1, P2 + 1 + Quest, cmp2());

        for(i = 1; i <= N; i++)
            for(j = 1; j <= N; j++)
            {
                Viz[i][j] = 0;
                TT[M[i][j]] = M[i][j];
                RG[M[i][j]] = M[i][j];
            }

        for(i = unde, j = 1; i;)
        {
            while(j <= Quest && V[sir[QU[P2[j]]]] > V[sir[i]]){
                if(find(M[Q[P2[j]][0].x][Q[P2[j]][0].y]) == find(M[Q[P2[j]][1].x][Q[P2[j]][1].y]))
                    Sol[P2[j]] += step;
                j++;
            }

            for(k = i; V[sir[k]] == V[sir[i]]; i--)
            {
                Viz[P[sir[i]].x][P[sir[i]].y] = 1;
                for(p = 0; p < 4; p++)
                {
                    cx = P[sir[i]].x + di[p];
                    cy = P[sir[i]].y + dj[p];

                    if(cx <= N && cx > 0 && cy <= N && cy > 0 && Viz[cx][cy])
                        Unite(find(M[P[sir[i]].x][P[sir[i]].y]), find(M[cx][cy]));
                }
            }
        }
        for( ; j <= Quest && V[sir[QU[P2[j]]]] > V[sir[i]]; j++)
            if(find(M[Q[P2[j]][0].x][Q[P2[j]][0].y]) == find(M[Q[P2[j]][1].x][Q[P2[j]][1].y]))
                Sol[P2[j]] += step;
        step >>= 1;
    }
    for(i = 1; i <= Quest; i++)
        printf("%d\n", V[sir[Sol[i]]]);

}
int main()
{
    read();
    solve();
    return 0;
}