Cod sursa(job #1623372)

Utilizator SmaugSmaug . Smaug Data 1 martie 2016 19:05:04
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.3 kb
#include <bits/stdc++.h>
using namespace std;

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

const int MAXN = 305;
const int MAXQ = 20005;

int n, q;
int a[MAXN][MAXN];

int id[MAXN][MAXN];
vector<int> g[MAXN * MAXN];

int len;
pair<int, int> sr[MAXN * MAXN];
bool vis[MAXN * MAXN];

struct Query {
  int left, right;
  int ans, i;
} v[MAXQ];

// disjoint

int dad[MAXN * MAXN];

inline int get(const int x) {
  if (dad[x] == x) {
    return x;
  }
  return (dad[x] = get(dad[x]));
}

inline void join(const int x, const int y) {
  dad[get(x)] = get(y);
}

inline void _clear() {
  for (int i = 0; i < MAXN * MAXN; ++i) {
    dad[i] = i;
    vis[i] = false;
  }
}

// ---

inline void add_edge(const int x, const int y) {
  g[x].push_back(y);
  g[y].push_back(x);
}

int main() {
  fin >> n >> q;
  for (int i = 1, foo = 0; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      id[i][j] = ++foo;
    }
  }
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      if (i < n) {
        add_edge(id[i][j], id[i + 1][j]);
      }
      if (j < n) {
        add_edge(id[i][j], id[i][j + 1]);
      }
    }
  }
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      fin >> a[i][j];
      sr[++len] = make_pair(a[i][j], id[i][j]);
    }
  }
  for (int i = 1; i <= q; ++i) {
    int x1, y1, x2, y2;
    fin >> x1 >> y1 >> x2 >> y2;
    v[i].left = id[x1][y1];
    v[i].right = id[x2][y2];
    v[i].i = i;
  }
  sort(sr + 1, sr + 1 + len,
    [&] (const pair<int, int> &x, const pair<int, int> &y) {
      return x.first > y.first;
    }
  );
  for (int cnt = 1 << 19; cnt > 0; cnt >>= 1) {
    sort(v + 1, v + 1 + q,
      [&] (const Query &x, const Query &y) {
        return x.ans > y.ans;
      }
    );
    _clear();
    int now = 1;
    for (int i = 1; i <= q; ++i) {
      while (now <= len && sr[now].first >= v[i].ans + cnt) {
        for (const auto node : g[sr[now].second]) {
          if (vis[node]) {
            join(sr[now].second, node);
          }
        }
        vis[sr[now].second] = true;
        ++now;
      }
      if (get(v[i].left) == get(v[i].right)) {
        v[i].ans += cnt;
      }
    }
  }
  sort(v + 1, v + 1 + q,
    [&] (const Query &x, const Query &y) {
      return x.i < y.i;
    }
  );
  for (int i = 1; i <= q; ++i) {
    fout << v[i].ans << '\n';
  }
  fout.close();
}