Cod sursa(job #2715819)

Utilizator PetyAlexandru Peticaru Pety Data 4 martie 2021 11:42:07
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda simularedelacasi1 Marime 2.52 kb
#include <bits/stdc++.h>
#define ll long long
#define ld long double
	
using namespace std;
	
const ll MOD = 1e9 + 7;
const ll INF = 1e9;
	
ifstream fin ("matrice2.in");
ofstream fout ("matrice2.out");
		
int dp[20][90002], a[302][302], p[90002];
vector<int>G[90002];
	
int dl[4] = {0, 0, -1, 1};	
int dc[4] = {1, -1, 0, 0};
	
int n, q;
	
int find (int x) {
  if (p[x] == x)
    return x;
  return p[x] = find(p[x]);
}
	
 
	
struct nod {
  int val, x, y;
  bool operator < (const nod a) const {
    if (a.val == val) {
      if (x != a.x)
        return x < a.x;
      else
        return y < a.y;
    }
    return val < a.val;
  }
};
	
vector<nod>v;
	
void Union (int x, int y) {
  if (find(x) == find(y))
    return;
  x = find(x);
  p[x] = y;
  G[y].push_back(x);
}
	
int poz[90002], sz[90002], euler;
	
void dfs (int nod,  int par) {
 dp[0][nod] = par;
 poz[nod] = ++euler;
 sz[nod] = 1;
 for (auto it : G[nod]) {
   dfs(it, nod); 
   sz[nod] += sz[it];
 }
}
	

int main()
	
{
	
  //ios_base::sync_with_stdio(false);
  //cin.tie(0); cout.tie(0);
  fin >> n >> q;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++) {
      fin >> a[i][j];
      p[(i - 1) * n + j] = i * n - n + j;
      v.push_back({a[i][j], i, j});
    }
  sort(v.begin(), v.end());
  for (int i = n * n; i >= 1; i--) {
    for (int k = 0; k < 4; k++) {
      int x = v[i - 1].x + dl[k];
      int y = v[i - 1].y + dc[k];
      if (x >= 1 && y <= n && x <= n && y >= 1)
        if (a[x][y] > v[i - 1].val || (a[x][y] == v[i - 1].val && x > v[i - 1].x) || (a[x][y] == v[i - 1].val && x == v[i - 1].x && y > v[i - 1].y)) {
          Union((x - 1) * n + y, (v[i - 1].x - 1) * n + v[i - 1].y);
        }
    }
  }
  int root = v[0].x * n - n + v[0].y;
  dfs(root, 0);
  for (int i = 1; (1 << i) <= n * n; i++)
    for (int j = 1; j <= n * n; j++)
      dp[i][j] = dp[i - 1][dp[i - 1][j]];
  while (q--) {
    int x1, y1, x2, y2;
    fin >> x1 >> y1 >> x2 >> y2;
    int nod1 = (x1 - 1) * n + y1;
    int nod2 = (x2 - 1) * n + y2;
    if (poz[nod1] <= poz[nod2] && poz[nod2] < poz[nod1] + sz[nod1]) {
      fout << a[x1][y1] << "\n";
      continue;
    }
    for (int i = 19; i >= 0; i--) {
      if (dp[i][nod1] != 0 && !(poz[dp[i][nod1]] <= poz[nod2] && poz[nod2] < poz[dp[i][nod1]] + sz[dp[i][nod1]])) {
        nod1 = dp[i][nod1];
      }
    }
    int b = dp[0][nod1];
    int lin = (b  - 1) / n + 1;
    int col = (b - 1) % n + 1;
    fout << a[lin][col] << "\n";
  }
  return 0;
	
}