Cod sursa(job #2783003)

Utilizator Alex_tz307Lorintz Alexandru Alex_tz307 Data 13 octombrie 2021 17:23:58
Problema Matrice 2 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.36 kb
#include <bits/stdc++.h>

using namespace std;

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

const int MAXN = 300;
const int MAXV = 1e6;
const int MAXQ = 2e4;
const int di[] = {-1, 0, 1, 0}, dj[] = {0, 1, 0, -1};
int a[1 + MAXN][1 + MAXN], sol[1 + MAXQ];
vector<pair<short, short>> cells[1 + MAXV];
pair<int, int> q[1 + MAXQ];

struct DSU {
  vector<int> p, sz;

  DSU(int n) {
    p.resize(n + 1);
    iota(p.begin(), p.end(), 0);
    sz.assign(n + 1, 1);
  }

  int root(int x) {
    if (x == p[x]) {
      return x;
    }
    return p[x] = root(p[x]);
  }

  bool unite(int u, int v) {
    int x = root(u), y = root(v);
    if (x == y) {
      return false;
    }
    if (sz[x] > sz[y]) {
      swap(x, y);
    }
    p[x] = y;
    sz[y] += sz[x];
    return true;
  }
};

void test_case() {
  int n, Q;
  fin >> n >> Q;
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      fin >> a[i][j];
      cells[a[i][j]].emplace_back(i, j);
    }
  }
  auto id = [&](int i, int j) -> int {
    return (i - 1) * n + j;
  };
  unordered_set<int> left;
  for (int i = 1; i <= Q; ++i) {
    int x1, y1, x2, y2;
    fin >> x1 >> y1 >> x2 >> y2;
    q[i] = make_pair(id(x1, y1), id(x2, y2));
    left.emplace(i);
  }
  DSU tree(n * n);
  auto inside = [&](int lin, int col) -> bool {
    return 1 <= min(lin, col) && max(lin, col) <= n;
  };
  for (int x = MAXV; x >= 1; --x) {
    if (left.empty() == true) {
      break;
    }
    bool ok = false;
    for (auto it : cells[x]) {
      int i, j;
      tie(i, j) = it;
      int curr_id = id(i, j);
      for (int k = 0; k < 4; ++k) {
        int iv = i + di[k], jv = j + dj[k];
        if (inside(iv, jv) == true && a[iv][jv] >= x) {
          if (tree.unite(curr_id, id(iv, jv))) {
            ok = true;
          }
        }
      }
    }
    if (ok == true) {
      vector<int> to_erase;
      for (int i : left) {
        if (tree.root(q[i].first) == tree.root(q[i].second)) {
          sol[i] = x;
          to_erase.emplace_back(i);
        }
      }
      for (int it : to_erase) {
        left.erase(it);
      }
    }
  }
  for (int i = 1; i <= Q; ++i) {
    fout << sol[i] << '\n';
  }
}

int main() {
  int t = 1;
  for (int tc = 1; tc <= t; ++tc) {
    test_case();
  }
  fin.close();
  fout.close();
  return 0;
}