Cod sursa(job #2549621)

Utilizator Robert_VRVRobert Vadastreanu Robert_VRV Data 17 februarie 2020 20:53:12
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.29 kb
#include <algorithm>
#include <fstream>
#include <string.h>
#include <vector>

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

const int MAX_N = 305;
const int MAX_Q = 20005;
const int INF = 1e9;
const int dl[4] = {-1, 0, 0, 1};
const int dc[4] = {0, -1, 1, 0};

int n, Q, nr;

struct Query {
  int begin, end;
  int answer;
  int index;
  bool operator <(const Query& other) const {
    return this->answer > other.answer;
  }
};

bool cmp(Query a, Query b) {
  return a.index < b.index;
}

struct Cell {
  int val;
  int ind;
  bool operator <(const Cell& other) {
    return this->val > other.val || (this->val == other.val && this->ind < other.ind);
  }
};
Cell cells[MAX_N * MAX_N];
int a[MAX_N][MAX_N];
Query queries[MAX_Q];

int father[MAX_N * MAX_N];

void reset() {
  for (int i = 0; i < nr; i++)
    father[i] = i;
}

int find_father(int k) {
  if (k != father[k])
    father[k] = find_father(father[k]);
  return father[k];
}

bool joined(int u, int v) {
  return find_father(u) == find_father(v);
}

void join(int u, int v) {
  u = find_father(u);
  v = find_father(v);
  father[u] = v;
}

void join(int u) {
  int i = u / n;
  int j = u % n;
  for (int h = 0; h < 4; h++) {
    int in = i + dl[h];
    int jn = j + dc[h];
    if (0 <= in && in < n && 0 <= jn && jn < n && a[in][jn] >= a[i][j])
      join(i * n + j, in * n + jn);
  }
}


int main() {

  fin >> n >> Q;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) {
      int x;
      fin >> x;
      a[i][j] = x;
      cells[nr] = Cell{x, nr};
      nr++;
    }
  std::sort(cells, cells + nr);
  for (int i = 0; i < Q; i++) {
    int a, b, c, d;
    fin >> a >> b >> c >> d;
    queries[i] = Query{(a - 1) * n + b - 1, (c - 1) * n + d - 1, 0, i};
  }
  for (int add = 20; add >= 0; add--) {
    reset();
    std::sort(queries, queries + Q);
    int j = 0;
    for (int i = 0; i < Q; i++) {
      while (j < nr && cells[j].val >= (1 << add) + queries[i].answer)
        join(cells[j++].ind);
      if (joined(queries[i].begin, queries[i].end)) {
        queries[i].answer += (1 << add);
      }
    }

  }
  std::sort(queries, queries + Q, cmp);
  for (int i = 0; i < Q; i++)
    fout << queries[i].answer << '\n';

  return 0;
}