Cod sursa(job #1804947)

Utilizator BlackLordFMI Alex Oprea BlackLord Data 13 noiembrie 2016 12:15:32
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.04 kb
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

ifstream fin ("matrice2.in");
ofstream fout ("matrice2.out");

const int NM = 100100, M = 310;

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

struct nush1{
    int k,p;
}V[NM];

struct nush2{
    int a, b, st, dr, ind;
}q[NM];

int i, n, m, T[NM], VA[NM], N, val, k, t1, x, ic, jc, t2, t, vm, po, R[NM], xc, A[M][M], j, yc, xu, yu;

vector<int> v[NM];

inline int cmp1(nush1 A, nush1 B) {
    return A.k < B.k;
}

inline int cmp2(nush2 A, nush2 B) {
    return A.a < B.a;
}

inline int cmp3(nush2 A, nush2 B) {
    return A.ind < B.ind;
}

void unite(int x, int y) {
    if(R[x] <= R[y]) {
        T[x] = y;
        if (R[x] == R[y]) {
            R[y]++;
        }
    } else {
        T[y]=x;
    }
}

int find(int x) {
    int aux = x;
    while (x != T[x]) {
        x = T[x];
    }
    int t = x;
    x = aux;
    while (x != t) {
        aux = T[x];
        T[x] = t;
        x = aux;
    }
    return t;
}

int main() {
    fin >> n >> m;
    for (i = 1; i <= n; ++i) {
        for (j = 1; j <= n; ++j) {
            fin >> V[(i - 1) * n + j].k;
            V[(i - 1) * n + j].p = (i - 1) * n + j;
            A[i][j] = (i - 1) * n + j;
        }
    }
    for (i = 1; i <= n; ++i) {
        for(j = 1; j <= n; ++j) {
            for (k = 0; k < 4; ++k) {
                ic = i + dx[k];
                jc = j + dy[k];
                if (ic < 1 || jc < 1 || ic > n || jc > n) {
                    continue;
                }
                v[A[i][j]].push_back(A[ic][jc]);
            }
        }
    }
    N = n * n;
    sort(V + 1,V + N + 1, cmp1);
    for (i = 1; i <= m; ++i) {
        fin >> xu >> yu >> xc >> yc;
        q[i].st = A[xu][yu];
        q[i].dr = A[xc][yc];
        q[i].ind = i;
    }
    vm = V[N].k;
    for (i = 1; i <= N; ++i) {
        VA[V[i].p] = V[i].k;
    }
    for (po = 1; po <= vm; po <<= 1);
    po >>= 1;
    for (; po; po >>= 1) {
        j = N;
        sort(q + 1, q + m + 1, cmp2);
        for (i = 1; i <= N; ++i) {
            R[i] = 1;
            T[i] = i;
        }
        for (i = m; i > 0; --i) {
            val = q[i].a + po;
            for (; j >= 1; --j) {
                if (V[j].k < val) {
                    break;
                }
                x = V[j].p;
                t1 = find(x);
                for (t = 0; t < v[x].size(); ++t) {
                    if (VA[v[x][t]] < val) {
                        continue;
                    }
                    t2 = find(v[x][t]);
                    if (t2 != t1) {
                        unite(t1, t2);
                    }
                    t1 = find(x);
                }
            }
            t1 = find(q[i].st);
            t2 = find(q[i].dr);
            if (t1 == t2) {
                q[i].a += po;
            }
        }
    }
    sort (q + 1, q + m + 1, cmp3);
    for (i = 1; i <= m; ++i) {
        fout << q[i].a << "\n";
    }
    return 0;
}