Cod sursa(job #1391888)

Utilizator SmarandaMaria Pandele Smaranda Data 18 martie 2015 11:19:21
Problema Matrice 2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.09 kb
#include <cstdio>
#include <algorithm>

using namespace std;

struct Query {
    int x1, y1, x2, y2, ans;
    int ind;
};

struct Node {
    int x, y, val;
};

class MyComp2 {
public :
    bool operator () (const Query &A, const Query &B) {
        return A.ans > B.ans;
    }
};


class MyComp {
public :
    bool operator () (const Node &A, const Node &B) {
        return A.val > B.val;
    }
};

const int N = 301, Q = 20002;

Node nodes [N * N];
Query a [Q];
int n, q, u, h [N * N], f [N * N], valori [N][N], ind [N][N], sol [Q];
int dx [] = {-1, 0, 1, 0};
int dy [] = {0, 1, 0, -1};

void init () {
    int i;

    for (i = 1; i <= u; i ++) {
        h [i] = 0;
        f [i] = i;
    }
}

int getFather (int x) {
    int father, t;

    for (t = x; f [t] != t; t = f [t]);
    father = t;
    t = x;
    while (f [t] != t) {
        x = f [t];
        f [t] = father;
        t = x;
    }
    return t;
}

void unite (const int &x, const int &y) {
    if (h [y] > h [x])
        f [x] = y;
    else f [y] = x;
    if (h [y] == h [x])
        h [x] ++;
}

bool inBox (const Node &A) {
    return (A.x >= 1 && A.x <= n && A.y >= 1 && A.y <= n);
}

void add (const Node &A) {
    int i, fA, fB;
    Node B;

    for (i = 0; i < 4; i ++) {
        B.x = A.x + dx [i];
        B.y = A.y + dy [i];
        if (inBox (B))
            if (valori [B.x][B.y] >= A.val) {
                B.val = valori [B.x][B.y];
                fA = getFather (ind [A.x][A.y]);
                fB = getFather (ind [B.x][B.y]);
                if (fA != fB)
                    unite (fA, fB);
            }
    }
}

int main () {
    int i, j, step, last, st, dr;

    freopen ("matrice.in", "r", stdin);
    freopen ("matrice.out", "w", stdout);

    scanf ("%d%d", &n, &q);
    u = 0;
    for (i = 1; i <= n; i ++)
        for (j = 1; j <= n; j ++) {
            scanf ("%d", &nodes [++ u].val);
            nodes [u].x = i;
            nodes [u].y = j;
            valori [i][j] = nodes [u].val;
        }

    sort (nodes + 1, nodes + 1 + u, MyComp ());

    for (i = 1; i <= u; i ++)
        ind [nodes [i].x][nodes [i].y] = i;

    for (i = 1; i <= q; i ++) {
        scanf ("%d%d%d%d", &a [i].x1, &a [i].y1, &a [i].x2, &a [i].y2);
        a [i].ans = 0;
        a [i].ind = i;
    }

    for (step = (1 << 19); step; step >>= 1) {
        init ();
        for (i = 1; i <= q; i ++)
            a [i].ans = a [i].ans + step;
        last = 1;
        sort (a + 1, a + 1 + q, MyComp2 ());
        for (i = 1; i <= q; i ++) {
            st = dr = 0;
            while (nodes [last].val >= a [i].ans) {
                add (nodes [last]);
                ++ last;
            }
            st = getFather (ind [a [i].x1][a [i].y1]);
            dr = getFather (ind [a [i].x2][a [i].y2]);
            if (st == dr)
                continue;
            else a [i].ans -= step;
        }
    }
    for (i = 1; i <= q; i ++)
        sol [a [i].ind] = a [i].ans;
    for (i = 1; i <= q; i ++)
        printf ("%d\n", sol [i]);
    return 0;
}