Cod sursa(job #1066189)

Utilizator blasterzMircea Dima blasterz Data 24 decembrie 2013 11:11:28
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.33 kb
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;
#define N 90003

int a[301][301];
int n, Q;
int xx[4] = {-1, 0, 1, 0};
int yy[4] = {0, 1, 0, -1};

struct nod {
    int i, j, v;
    nod(){};
    nod(int _i, int _j, int _v) { i = _i; j = _j; v = _v;};
};

nod x[N];
int nx;

int q[20001][4];
int I[20001];
int ICNT[20001];
int query[20001];
int t[N];
int pos[301][301];


struct cmp {
    bool operator()(const nod &a, const nod &b) const {
        if (a.v > b.v)
            return true;
        return false;
    }
};
struct cmp2 {
    bool operator()(const int &a, const int &b) const {
        return I[a] > I[b];
    }
};

inline int find(int i) {
    if (i != t[i])
        t[i] = find(t[i]);
    return t[i];
}

inline int uneste(int i, int j) {
    i = find(i);
    j = find(j);
    if (i == j)
        return 0;
    t[i] = j;
    return 1;
}

int main() {
    freopen ("matrice2.in", "r", stdin);
    freopen ("matrice2.out", "w", stdout);
    scanf ("%d %d\n", &n, &Q);
    int i, j, k, cnt;
    for (i = 1; i <= n; ++i)
        for (j = 1; j <= n; ++j) {
            scanf ("%d ", &a[i][j]);
            x[++nx] = nod(i, j, a[i][j]);
        }
    sort(x + 1, x + nx + 1, cmp());
    for (i = 1; i <= nx; ++i)
        pos[ x[i].i ][ x[i].j ] = i;
    for (i = 1; i <= Q; ++i)
        scanf ("%d %d %d %d\n", &q[i][0], &q[i][1], &q[i][2], &q[i][3]);
    
    for (cnt = 1; cnt <= x[1].v; cnt *= 2);
    for (; cnt ; cnt >>= 1) {
        
        for (i = 1; i <= Q; ++i)
            ICNT[i] = I[i] + cnt,
            query[i] = i;
        for (i = 1; i <= nx; ++i)
            t[i] = i;
        sort(query + 1, query + Q + 1, cmp2());
        
        for (i = 1, j = 1; i <= Q ; ++i) {
            for (; j <= nx && ICNT[query[i]] <= x[j].v ; ++j) {
                for (k = 0; k < 4; ++k) {
                    int nx = x[j].i + xx[k];
                    int ny = x[j].j + yy[k];
                    if (nx >= 1 && nx <= n && ny >= 1 && ny <= n && a[nx][ny] >= ICNT[query[i]]) {
                        uneste(j, pos[nx][ny]);
                    }
                }
            }
            if (find( pos[ q[ query[i] ][0] ][ q[ query[i] ][1] ]) ==
                    find( pos[ q[ query[i] ][2] ][ q[ query[i] ][3] ]))
                I[query[i]] += cnt;
        }
    }
    
    for (i = 1; i <= Q; ++i)
        printf ("%d\n", I[i]);
}