Cod sursa(job #2556860)

Utilizator sichetpaulSichet Paul sichetpaul Data 25 februarie 2020 11:27:46
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.49 kb
#include <bits/stdc++.h>
#define Qmax 100005
#define Nmax 302
using namespace std;

ifstream f("matrice2.in");
ofstream g("matrice2.out");

int N, K, Q;
int a[Nmax][Nmax];
bool vis[Nmax * Nmax];
struct query{
   int le, ri, mid, pos, ans, x, y;
};
query q[Qmax];
bool cmp1(query a, query b) {
   return a.mid < b.mid;
}
bool cmp2(query a, query b) {
   return a.pos < b.pos;
}

struct cell{
    int x, y, val;
};
cell v[Nmax * Nmax];
bool cmp3(cell a, cell b) {
    return a.val < b.val;
}

///
int h[Nmax * Nmax], t[Nmax * Nmax];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};

int root(int x) {
   while (t[x]) x = t[x];
   return x;
}
int Pos(int x, int y) {
   return (x - 1) * N + y;
}
bool in(int i, int j) {
   if (i < 1 || i > N) return 0;
   if (j < 1 || j > N) return 0;
   return 1;
}
void unite(int x, int y) {
    int rx = root(x), ry = root(y);
    if (h[rx] < h[ry]) swap(rx, ry);
    t[ry] = rx;
    if (h[rx] == h[ry]) ++h[rx];
}
int main()
{
    f >> N >> Q;
    for (int i = 1; i <= N; ++i)
    for (int j = 1; j <= N; ++j) {
        f >> a[i][j];
        v[++K] = {i, j, a[i][j]};
    }
    sort(v + 1, v + K + 1, cmp3);

    for (int i = 1; i <= Q; ++i) {
        int x1, y1, x2, y2;
        f >> x1 >> y1 >> x2 >> y2;
        q[i].pos = i;
        q[i].le = 1, q[i].ri = K, q[i].mid = (K + 1) / 2;
        q[i].x = Pos(x1, y1), q[i].y = Pos(x2, y2);
    }

    bool ok = 1;
    while (ok) {
       for (int i = 1; i <= K; ++i)
          h[i] = t[i] = vis[i] = 0;
       sort(q + 1, q + Q + 1, cmp1);

       int j = Q;
       for (int i = K; i >= 1; --i) {
            vis[Pos(v[i].x, v[i].y)] = 1;
           for (int p = 0; p < 4; ++p) {
              int lin = v[i].x + dx[p], col = v[i].y + dy[p];
              if (!in(lin, col) || vis[Pos(lin,col)] == 0) continue;
              int a = Pos(v[i].x, v[i].y), b = Pos(lin, col);
                if (root(a) != root(b)) unite(a, b);
           }

            while (j && q[j].mid == i) {
                if (root(q[j].x) == root(q[j].y))
                    q[j].ans = v[i].val, q[j].le = i + 1;
                else q[j].ri = i - 1;
                --j;
            }
       }


        ok = 0;
        for (int i = 1; i <= Q; ++i)
          if (q[i].le <= q[i].ri) ok = 1, q[i].mid = (q[i].ri + q[i].le) / 2;
          else q[i].mid = 0;
    }

    sort(q + 1, q + Q + 1, cmp2);
    for (int i = 1; i <= Q; ++i)
        g << q[i].ans << '\n';

    return 0;
}