Cod sursa(job #325529)

Utilizator bogdan2412Bogdan-Cristian Tataroiu bogdan2412 Data 21 iunie 2009 00:05:15
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.66 kb
#include <cstdio>
#include <list>
#include <cassert>
#include <algorithm>
#include <vector>

using namespace std;

#define MAXN 305
#define MAXC 90005
#define MAXQ 20005

int N, Q;
int m[MAXN][MAXN];

vector<pair<int, int> > v;
int cur_val;

const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};

int Q1[MAXQ], Q2[MAXQ], Qr[MAXQ];
list<int> Qmap[MAXC];
int p[MAXC], nrQ[MAXC];

inline int getSet(int x) {
    if (x == p[x]) {
        return x;
    }
    return p[x] = getSet(p[x]);
}

inline void unite(int x, int y) {
    x = getSet(x);
    y = getSet(y);

    if (x == y) {
        return;
    }
    if (nrQ[x] > nrQ[y]) {
        swap(x, y);
    }

    p[x] = y;
    nrQ[y] += nrQ[x];
    list<int> :: iterator it;
    for (it = Qmap[x].begin(); it != Qmap[x].end(); it++) {
        // Lazy delete queries that have already been answered
        if (Q1[*it] == Q2[*it]) {
            continue;
        }

        if (Q1[*it] == x) {
            Q1[*it] = y;
        }
        if (Q2[*it] == x) {
            Q2[*it] = y;
        }

        if (Q1[*it] == Q2[*it]) {
            // Woo-hoo we have an answer
            Qr[*it] = cur_val;
            continue;
        }

        // Add this query to Qmap[y]
        Qmap[y].push_back(*it);
    }
    Qmap[x].clear();
}

int main() {
    freopen("matrice2.in", "rt", stdin);
    freopen("matrice2.out", "wt", stdout);

    scanf("%d %d", &N, &Q);
    v.clear();
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            scanf("%d ", m[i] + j);
            v.push_back(make_pair(m[i][j], i * N + j));
        }
    }
    sort(v.begin(), v.end());
    reverse(v.begin(), v.end());

    for (int i = 0; i < Q; i++) {
        int X1, Y1, X2, Y2;
        scanf("%d %d %d %d", &X1, &Y1, &X2, &Y2);
        X1 -= 1; Y1 -= 1;
        X2 -= 1; Y2 -= 1;

        Q1[i] = X1 * N + Y1;
        Q2[i] = X2 * N + Y2;
        Qmap[Q1[i]].push_back(i);
        Qmap[Q2[i]].push_back(i);
    }

    for (int i = 0; i < N * N; i++) {
        p[i] = i;
        nrQ[i] = Qmap[i].size();
    }

    for (int i = 0; i < N * N; ) {
        cur_val = v[i].first;

        int j;
        for (j = i; j < N * N && v[i].first == v[j].first; j++) {
            int x = v[j].second / N, y = v[j].second % N;
            for (int k = 0; k < 4; k++) {
                int _x = x + dx[k];
                int _y = y + dy[k];
                if (_x < 0 || _x >= N || _y < 0 || _y >= N)
                    continue;
                if (m[_x][_y] < cur_val)
                    continue;

                unite(x * N + y, _x * N + _y);
            }
        }
        i = j;
    }

    for (int i = 0; i < Q; i++) {
        printf("%d\n", Qr[i]);
    }

    return 0;
}