Cod sursa(job #2783196)

Utilizator Alex_tz307Lorintz Alexandru Alex_tz307 Data 13 octombrie 2021 22:55:24
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.71 kb
#include <bits/stdc++.h>

using namespace std;

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

const int MAXN = 3e2;
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][1 + MAXN + 1], rev[1 + MAXN * MAXN], sol[1 + MAXQ];
pair<short, short> cells[1 + MAXN * MAXN];
vector<pair<short, short>> pos[1 + MAXN * MAXN];
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;
  }
};

bool cmp(const pair<short, short> &x, const pair<short, short> &y) {
  return a[x.first][x.second] < a[y.first][y.second];
}

void test_case() {
  int n, Q;
  fin >> n >> Q;
  auto id = [&](int i, int j) -> int {
    return (i - 1) * n + j;
  };
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      fin >> a[i][j];
      cells[id(i, j)] = make_pair(i, j);
    }
  }
  int N = n * n;
  sort(cells + 1, cells + N + 1, cmp);
  int m = 0, last = 0;
  for (int i = 1; i <= N; ++i) {
    int l, c;
    tie(l, c) = cells[i];
    if (a[l][c] != last) {
      rev[++m] = a[l][c];
      last = a[l][c];
    }
    pos[m].emplace_back(l, c);
  }
  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));
  }
  int step = 1;
  while ((step << 1) <= m) {
    step <<= 1;
  }
  while (step >= 1) {
    vector<int> aux(Q + 1), qt[m + 1];
    for (int i = 1; i <= Q; ++i) {
      if (sol[i] + step <= m) {
        aux[i] = sol[i] + step;
        qt[aux[i]].emplace_back(i);
      }
    }
    DSU t(N);
    for (int p = m; p >= 1; --p) {
      for (auto it : pos[p]) {
        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 (a[i][j] <= a[iv][jv]) {
            t.unite(curr_id, id(iv, jv));
          }
        }
      }
      for (int i : qt[p]) {
        if (t.root(q[i].first) == t.root(q[i].second)) {
          sol[i] = aux[i];
        }
      }
    }
    step >>= 1;
  }
  for (int i = 1; i <= Q; ++i) {
    fout << rev[sol[i]] << '\n';
  }
}

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