Cod sursa(job #1068760)

Utilizator tudorv96Tudor Varan tudorv96 Data 28 decembrie 2013 18:38:10
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.35 kb
#include <fstream>
#include <algorithm>
#include <iostream>
using namespace std;

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

const int N = 305;

struct query {
    pair <int, int> s, f;
    int poz, ans;
};

int a[N][N], t[N*N], q, sol[N*N/4], n;
pair <int, int> v[N*N];
query Q[N*N/4];

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

void unite(int x, int y) {
    int X = min(find(x), find(y)), Y = max(find(x), find(y));
    t[Y] = X;
}

bool query_cmp(query a, query b) {
    return a.ans > b.ans;
}

bool elem_cmp (pair <int, int> x, pair <int, int> y) {
    return a[x.first][x.second] > a[y.first][y.second];
}

int main() {
    fin >> n >> q;
    int k = 0;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j) {
            fin >> a[i][j];
            v[++k].first = i;
            v[k].second = j;
        }
    for (int i = 0; i < q; ++i) {
        fin >> Q[i].s.first >> Q[i].s.second >> Q[i].f.first >> Q[i].f.second;
        Q[i].poz = i;
    }
    fin.close();
    sort(v+1, v+k+1, elem_cmp);
    for (int step = (1 << 20); step; step >>= 1) {
        sort (Q, Q+q, query_cmp);
        for (int i = 1; i <= k; ++i)
            t[i] = 0;
        int i = 1;
        for (int j = 0; j < q; ++j) {
            for (; i <= k && Q[j].ans + step <= a[v[i].first][v[i].second]; ++i) {
                int poz = (v[i].first - 1) * n + v[i].second;
                t[poz] = poz;
                int up = poz - n, down = poz + n, left = poz - 1, right = poz + 1;
                if (up > 0 && find(up) && find(up) != find(poz))
                    unite (up, poz);
                if (down <= n * n && find(down) && find(down) != find(poz))
                    unite (down, poz);
                if (left % n && find(left) && find(left) != find(poz))
                    unite (left, poz);
                if (right % n != 1 && find(right) && find(right) != find(poz))
                    unite (right, poz);
            }
            int F[2] = {find((Q[j].s.first - 1) * n + Q[j].s.second), find((Q[j].f.first - 1) * n + Q[j].f.second)};
            if (F[0] && F[1] && F[0] == F[1])
                sol[Q[j].poz] += step, Q[j].ans += step;
        }
    }
    for (int i = 0; i < q; ++i)
        fout << sol[i] << "\n";
    fout.close();
}