Cod sursa(job #1348903)

Utilizator thewildnathNathan Wildenberg thewildnath Data 19 februarie 2015 21:41:57
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.7 kb
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

const int NMAX = 300;
const int QMAX = 20000;

struct punct
{
    int x, y;
    punct (int x = 0, int y = 0)
    {
        this->x = x;
        this->y = y;
    }
};

punct st[QMAX + 1], fin[QMAX + 1];
int num[NMAX + 1][NMAX + 1], t[NMAX * NMAX + 1];
bool viz[NMAX + 1][NMAX + 1];
int med[QMAX + 1], sol[QMAX + 1];
int val[NMAX * NMAX + 1], x[NMAX * NMAX + 1], y[NMAX * NMAX + 1];
int p1[NMAX * NMAX + 1], p2[QMAX + 1];
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};

int tata (int x)
{
    if (x != t[x])
        t[x] = tata (t[x]);
    return t[x];
}

inline bool cmp (int a, int b)
{
    return med[a] > med[b];
}

inline bool cmp2 (int a, int b)
{
    return val[a] > val[b];
}

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

    int n, q, nr = 0, cx, cy;

    scanf ("%d%d", &n, &q);
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= n; ++j)
        {
            ++nr;
            p1[nr] = nr;
            x[nr] = i;
            y[nr] = j;
            scanf ("%d", &val[nr]);
            num[i][j] = nr;
        }
    }
    for (int i = 1; i <= q; ++i)
        scanf ("%d%d%d%d", &st[i].x, &st[i].y, &fin[i].x, &fin[i].y);
    sort (p1 + 1, p1 + 1 + nr, cmp2);

    int pas = 1;
    while (pas < val[p1[1]]) pas <<= 1;

    for (; pas; pas >>= 1)
    {
        for (int i = 1; i <= q; ++i)
        {
            p2[i] = i;
            med[i] = sol[i] + pas;
        }
        sort (p2 + 1, p2 + 1 + q, cmp);

        for (int i = 1; i <= nr; ++i)
            t[i] = i;
        memset (viz, 0, sizeof (viz));

        int j = 1;
        for (int i = 1; i <= nr;)
        {
            for (int k = j; k <= q && med[p2[j]] > val[p1[i]]; ++j)
                if (tata (num[st[p2[j]].x][st[p2[j]].y]) == tata (num[fin[p2[j]].x][fin[p2[j]].y]))
                    sol[p2[j]] += pas;

            for (int k = i; i <= nr && val[p1[i]] == val[p1[k]]; ++i)
            {
                viz[x[p1[i]]][y[p1[i]]] = true;

                for (int d = 0; d < 4; ++d)
                {
                    cx = x[p1[i]] + dx[d];
                    cy = y[p1[i]] + dy[d];

                    if (cx > 0 && cx <= n && cy > 0 && cy <= n && viz[cx][cy])
                        t[tata (num[cx][cy])] = t[p1[i]];
                }
            }
        }

        for (;j <= q; ++j)
            if (tata (num[st[p2[j]].x][st[p2[j]].y]) == tata (num[fin[p2[j]].x][fin[p2[j]].y]))
                sol[p2[j]] += pas;
    }

    for (int i = 1; i <= q; ++i)
        printf ("%d\n", sol[i]);

    return 0;
}