Cod sursa(job #2271158)

Utilizator MiricaMateiMirica Matei MiricaMatei Data 28 octombrie 2018 10:42:26
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.84 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 305;
const int MAXM = 20005;

struct Node {
  int val, ind;
  bool operator < (const Node& other) const {
    return val > other.val;
  }
}v[MAXN * MAXN];

int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};

vector<int>G[MAXN * MAXN];

struct Query {
  int st, dr, last, u, v, ind;
}q[MAXM], s1[MAXM], s2[MAXM];

int t[MAXN * MAXN], h[MAXN * MAXN];
bool viz[MAXN * MAXN];

int f(int x) {
  int aux = x;
  while (x != t[x])
    x = t[x];
  while (aux != x) {
    int a = t[aux];
    t[aux] = x;
    aux = a;
  }
  return x;
}

void u(int x, int y) {
  x = f(x);
  y = f(y);
  if (x == y)
    return ;
  if (h[x] < h[y])
    swap(x, y);
  t[y] = x;
  if (h[x] == h[y])
    h[x]++;
}

void add(int node) {
  viz[node] = 1;
  for (auto it:G[node])
    if (viz[it])
      u(it, node);
}

bool ok(int x, int y) {
  return (f(x) == f(y));
}

void solve(int n, int m) {
  for (int pas = 20; pas > 0; --pas) {
    for (int i = 1; i <= n; ++i) {
      t[i] = i;
      h[i] = 1;
      viz[i] = 0;
    }
    int i = 1, j = 1, k1 = 0, k2 = 0;
    while (i <= n && j <= m) {
      while (i <= n && v[i].val >= (q[j].st + q[j].dr) / 2)
        add(v[i++].ind);
      while (j <= m && v[i].val < (q[j].st + q[j].dr) / 2)
        if (ok(q[j].u, q[j].v)) {
          q[j].last = (q[j].st + q[j].dr) / 2;
          q[j].st = (q[j].st + q[j].dr) / 2 + 1;
          s1[++k1] = q[j++];
        } else {
          q[j].dr = (q[j].st + q[j].dr) / 2 - 1;
          s2[++k2] = q[j++];
        }
    }
    i = j = 1;
    m = 0;
    while (i <= k1 && j <= k2) {
      if (s1[i].st + s1[i].dr >= s2[j].st + s2[j].dr)
        q[++m] = s1[i++];
      else
        q[++m] = s2[j++];
    }
    while (i <= k1)
      q[++m] = s1[i++];
    while (j <= k2)
      q[++m] = s2[j++];
  }
}

int sol[MAXN];

int main() {
  freopen("matrice2.in", "r", stdin);
  freopen("matrice2.out", "w", stdout);

  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n; ++j) {
      int x;
      scanf("%d", &x);
      v[(i - 1) * n + j] = {x, (i - 1) * n + j};
    }
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n; ++j)
      for (int k = 0; k < 4; ++k) {
        int i1 = i + dx[k];
        int j1 = j + dy[k];
        if (i1 != 0 && i1 != n + 1 && j1 != 0 && j1 != n + 1)
          G[(i - 1) * n + j].push_back((i1 - 1) * n + j1);
      }

  sort(v + 1, v + n * n + 1);

  for (int i = 1; i <= m; ++i) {
    int x1, y1, x2, y2;
    scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
    q[i] = {1, 1000000, 0, (x1 - 1) * n + y1, (x2 - 1) * n + y2, i};
  }

  solve(n * n, m);

  for (int i = 1; i <= m; ++i)
    sol[q[i].ind] = q[i].last;

  for (int i = 1; i <= m; ++i)
    printf("%d\n", sol[i]);

  return 0;
}