Cod sursa(job #2680784)

Utilizator iancupoppPopp Iancu Alexandru iancupopp Data 4 decembrie 2020 13:02:26
Problema Matrice 2 Scor 85
Compilator cpp-64 Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 3.72 kb
#include <fstream>
#include <algorithm>
#include <list>

using namespace std;

struct elem {
    int cost;
    int poz;
    bool operator<(const elem& e) {
        return cost < e.cost;
    }
};

struct query {
    int x[2];
    int y[2];
};

const int N = 90001, Q = 20000;

elem m[N];
query q[Q];
list<int> l[N];
int sef[N], rez[Q], c[N], n;

void unire(int a, int b) {
    auto it_a = l[a].begin();
    auto it_b = l[b].begin();
    list<int>::iterator aux;
    int qa, qb;
    while (it_a != l[a].end() && it_b != l[b].end()) {
        qa = *it_a;
        qb = *it_b;
        if (rez[qa])
            ++it_a;
        else if (rez[qb]) {
            aux = it_b++;
            l[b].erase(aux);
        }
        else if (qa == qb) {
            rez[qa] = c[a];
            ++it_a;
            aux = it_b++;
            l[b].erase(aux);
        }
        else if (qb > qa) {
            l[b].insert(it_b, qa);
            ++it_a;
        }
        else
            ++it_b;
    }
    while (it_a != l[a].end()) {
        qa = *it_a;
        if (!rez[qa])
            l[b].push_back(qa);
        ++it_a;
    }
    l[a].clear();
}

int sefsuprem(int x) {
    if (sef[x] == x)
        return x;
    return sef[x] = sefsuprem(sef[x]);
}

void adaug(elem e) {
    int poz, sef1, sef2;
    if (e.poz > n) {
        poz = e.poz - n;
        if (c[poz] >= e.cost) {
            sef1 = sefsuprem(e.poz);
            sef2 = sefsuprem(poz);
            if (sef1 != sef2) {
                c[sef1] = c[sef2] = e.cost;
                if (!l[sef1].empty())
                    unire(sef1, sef2);
                sef[sef1] = sef2;
            }
        }
    }
    if (e.poz % n) {
        poz = e.poz + 1;
        if (c[poz] >= e.cost) {
            sef1 = sefsuprem(e.poz);
            sef2 = sefsuprem(poz);
            if (sef1 != sef2) {
                c[sef1] = c[sef2] = e.cost;
                if (!l[sef1].empty())
                    unire(sef1, sef2);
                sef[sef1] = sef2;
            }
        }
    }
    if (e.poz <= n * (n - 1)) {
        poz = e.poz + n;
        if (c[poz] >= e.cost) {
            sef1 = sefsuprem(e.poz);
            sef2 = sefsuprem(poz);
            if (sef1 != sef2) {
                c[sef1] = c[sef2] = e.cost;
                if (!l[sef1].empty())
                    unire(sef1, sef2);
                sef[sef1] = sef2;
            }
        }
    }
    if (e.poz % n != 1) {
        poz = e.poz - 1;
        if (c[poz] >= e.cost) {
            sef1 = sefsuprem(e.poz);
            sef2 = sefsuprem(poz);
            if (sef1 != sef2) {
                c[sef1] = c[sef2] = e.cost;
                if (!l[sef1].empty())
                    unire(sef1, sef2);
                sef[sef1] = sef2;
            }
        }
    }
}

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

    int t, cmax = 0;
    in >> n >> t;
    for (int i = 1; i <= n * n; ++i) {
        in >> m[i].cost;
        c[i] = m[i].cost;
        cmax = max(cmax, c[i]);
        m[i].poz = i;
    }
    int poz;
    for (int i = 0; i < t; ++i) {
        in >> q[i].x[0] >> q[i].y[0] >> q[i].x[1] >> q[i].y[1];
        for (int j = 0; j < 2; ++j) {
            poz = n * (q[i].x[j] - 1) + q[i].y[j];
            l[poz].push_back(i);
        }
    }

    sort(m + 1, m + n * n + 1);
    for (int i = 1; i <= n * n; ++i)
        sef[i] = i;

    int i = n * n;
    for (int cost = cmax; cost > 0 && i > 0; --cost)
        while (m[i].cost == cost) {
            adaug(m[i]);
            --i;
        }
    for (int i = 0; i < t; ++i)
        out << rez[i] << '\n';

    in.close();
    out.close();
    return 0;
}