Cod sursa(job #3040263)

Utilizator dorufDoru Floare doruf Data 29 martie 2023 17:09:27
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.52 kb
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using pii = pair<int,int>;
#define eb emplace_back

const string TASK("matrice2");

ifstream fin(TASK + ".in");
ofstream fout(TASK + ".out");

const int N = 300 + 5;
const int MQ = 20000 + 5;
int a[N][N], n, Q;
int ans[MQ];

inline int f(const int& i, const int& j) {
  if (i < 1 || i > n || j < 1 || j > n) return 0;
  return (i-1) * n + j;
}

struct DSU {
  int t[N*N], n;
  void init(int _n) {
    n = _n;
    for (int i = 1; i <= n; ++i)
      t[i] = i;
  }
  int root(int x) {
    if (x == t[x]) return x;
    return t[x] = root(t[x]);
  }
  void join(int x, int y) {
    int rx = root(x), ry = root(y);
    if (rx != ry)
      t[rx] = ry;
  }
  bool connected(int x, int y) {
    int rx = root(x), ry = root(y);
    return (rx == ry);
  }
};

struct Edge {
  int u, v, w;
  Edge(){}
  Edge(int u, int v, int w) : u(u),v(v),w(w){}
  bool operator < (const Edge& oth) const {
    return w > oth.w;
  }
};

struct Query {
  int from, to, l, r, mid, idx;
  bool operator < (const Query& oth) const {
    return mid > oth.mid;
  }
};
Query q[MQ];
vector<Edge> edges;
DSU dsu;

int32_t main() {
  fin >> n >> Q;
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n; ++j)
      fin >> a[i][j];

  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n; ++j) {
      if (f(i+1, j))
        edges.eb(Edge(f(i,j),f(i+1,j),min(a[i][j],a[i+1][j])));
      if (f(i, j+1))
        edges.eb(Edge(f(i,j),f(i,j+1),min(a[i][j],a[i][j+1])));
    }
  sort(edges.begin(), edges.end());

  dsu.init(n * n);
  for (int is, ij, js, jj, i = 1; i <= Q; ++i) {
    fin >> is >> js; q[i].from = f(is, js);
    fin >> ij >> jj; q[i].to = f(ij, jj);
    q[i].l = 1, q[i].r = 1e6;
    q[i].idx = i;
  }
  for (int step = 1; step <= 20; ++step) {
    for (int i = 1; i <= Q; ++i)
      q[i].mid = (q[i].l + q[i].r) / 2;
    sort(q + 1, q + Q + 1);

    dsu.init(n * n);
    int j = 0;
    for (int i = 1; i <= Q; ++i) {
      //if (q[i].l == q[i].r) continue;
      while (j < edges.size() && edges[j].w >= q[i].mid) {
        dsu.join(edges[j].u, edges[j].v);
        ++j;
      }
      if (dsu.connected(q[i].from, q[i].to)) {
        ans[q[i].idx] = q[i].mid;
        q[i].l = q[i].mid + 1;
      } else q[i].r = q[i].mid - 1;
    }
    //for (int i = 1; i <= Q; ++i)
    //fout << q[i].l << ' ' << q[i].mid << ' ' << q[i].r << '\n';
  }

  for (int i = 1; i <= Q; ++i)
    fout << ans[i] << '\n';
}