Cod sursa(job #2256916)

Utilizator theodor.moroianuTheodor Moroianu theodor.moroianu Data 9 octombrie 2018 13:17:34
Problema Matrice 2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.7 kb
#include <bits/stdc++.h>
#define id(x, y) ((x) * n + y)
using namespace std;

int n, m;
vector <pair <int, int>> dir = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
const int NMAX = 310 * 310;

namespace UF {
    int tata[NMAX], g[NMAX];
    bool activ[NMAX];
    int find(int x) {
        if (!activ[x])
            return x;
        if (tata[tata[x]] != tata[x])
            tata[x] = find(tata[x]);
        return tata[x];
    }
    void unite(int a, int b) {
        a = find(a);
        b = find(b);
        if (a == b)
            return;
        if (g[a] >= g[b])
            tata[b] = a, g[a] += g[b];
        else
            tata[a] = b, g[b] += g[a];
    }
    void add(int x, int y) {
        int nr = id(x, y);
        activ[nr] = 1;
        tata[nr] = nr, g[nr] = 1;
        for (auto i : dir)
            if (activ[id(x + i.first, y + i.second)])
                unite(nr, id(x + i.first, y + i.second));
    }
    void reset() {
        memset(tata, 0, sizeof tata);
        memset(activ, 0, sizeof activ);
        memset(g, 0, sizeof g);
    }
    bool same(int x1, int y1, int x2, int y2) {
        return find(id(x1, y1)) == find(id(x2, y2));
    }
}

struct Q {
    int x1, y1, x2, y2, t, id;
    bool operator< (const Q & x) const {
        return t < x.t;
    }
};

vector <Q> events;
vector <tuple <int, int, int>> v;

int main()
{
    ifstream in("matrice2.in");
    ofstream out("matrice2.out");

    int x;
    in >> n >> m;

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            in >> x;
            v.push_back(make_tuple(x, i, j));
        }
    }

    sort(v.rbegin(), v.rend());

    events.resize(m);

    for (int i = 0; i < m; i++) {
        in >> events[i].x1 >> events[i].y1;
        in >> events[i].x2 >> events[i].y2;
        events[i].id = i;
        events[i].t = 0;
    }

    for (int q = 20; q >= 0; q--) {
        for (auto & i : events)
            i.t += (1 << q);
        for (int i = 0, j = 0; i < events.size(); i++) {
            //cout << get <0> (v[j]) << ' ' << events[i].t << '\n';
            while (j < v.size() && get <0> (v[j]) >= events[i].t) {
                UF::add(get <1> (v[j]), get <2> (v[j]));
                j++;
              //  cout << get <0> (v[j]) << '\n';
            }
            if (!UF::same(events[i].x1, events[i].y1,
                         events[i].x2, events[i].y2))
                events[i].t -= (1 << q);
        }
        UF::reset();
        sort(events.rbegin(), events.rend());
    }

    vector <int> ans(m);

    for (auto i : events)
        ans[i.id] = i.t;

    for (auto i : ans)
        out << i << '\n';

    return 0;
}