Cod sursa(job #2845773)

Utilizator cadmium_Voicu Mihai Valeriu cadmium_ Data 8 februarie 2022 12:14:07
Problema Matrice 2 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.16 kb
#include <bits/stdc++.h>
#define pii pair<int,int> 
using namespace std;

/*
 * (Ca) Sa moara tanta de ciuda in puscarie, de-aia
 * -- Nelu 2021
 */ 
 
#define cin fin
#define cout fout
class InParser {
private:
	FILE *fin;
	char *buff;
	int sp;
 
	char read_ch() {
		++sp;
		if (sp == 100000) {
			sp = 0;
			fread(buff, 1, 100000, fin);
		}
		return buff[sp];
	}
 
public:
	InParser(const char* nume) {
		fin = fopen(nume, "r");
		buff = new char[100000]();
		sp = 100000 - 1;
	}
	
	InParser& operator >> (int &n) {
		char c;
		while (!isdigit(c = read_ch()) && c != '-');
		int sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		} else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}
	
	InParser& operator >> (long long &n) {
		char c;
		n = 0;
		while (!isdigit(c = read_ch()) && c != '-');
		long long sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		} else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}
} cin("matrice2.in");
ofstream cout("matrice2.out");

const int nmax = 3e2 + 5;
const int qmax = 5e5 + 5;

int n, q;
int mat[nmax][nmax];
int temp[qmax];
int sol[qmax];
struct qry {
  int x1, y1, x2, y2, val, ind;
  bool operator <(const qry& a) {
    return pii{val, -ind} > pii{a.val, -a.ind};
  }
};

namespace DSU {
  int dsu[nmax * nmax];
  void reset() {
    for(int i = 1; i <= n; i++) {
      for(int j = 1; j <= n; j++) {
        dsu[i * n + j] = i * n + j;
      }
    }
  }
  int father(int a) {
    return (dsu[a] == a? a : father(dsu[a] = father(dsu[dsu[a]])));
  }
  void unite(int x1, int y1, int x2, int y2) {
    //cout << x1 << ' ' << y1 << "---" << x2  << ' ' << y2 << '\n';
    x1 = father(x1 * n + y1);
    x2 = father(x2 * n + y2);
    dsu[x1] = x2;
  }
  bool query(int x1, int y1, int x2, int y2) {
    x1 = father(x1 * n + y1);
    x2 = father(x2 * n + y2);
    return dsu[x1] == dsu[x2];
  }
}

vector<qry> qs; 

int dirx[4] = {1, -1, 0, 0};
int diry[4] = {0, 0, 1, -1};

#define set nuaia
qry all[110005];
static void set() {
  copy(qs.begin(), qs.end(), all);
  int cnt = qs.size()
  DSU::reset();
  for(int i = 1; i <= n; i++) {
    for(int j = 1; j <= n; j++) {
      all[cnt++] = qry{i, j, i, j, mat[i][j], -1};
    }
  }
  sort(all,all + cnt);
  for(int i = 0; i < cnt; i++) {
    auto x = all[i];
    if(x.ind == -1) {
      for(int i = 0; i < 4; i++) {
        if(mat[x.x1 + dirx[i]][x.y1 + diry[i]] >= x.val)
        DSU::unite(x.x1, x.y1, x.x1 + dirx[i], x.y1 + diry[i]);
      }
    }
    else {
      //cout << x.val << ' ' << x.x1 << ' ' << x.y1 << ' ' << x.x2 <<' '<< x.y2 << '\n';
      if(DSU::query(x.x1, x.y1, x.x2, x.y2))
        sol[x.ind] = x.val;
    }
  }
}


int main() {
  cin >> n >> q;
  for(int i = 1; i <= n; i++) {
    for(int j = 1; j <= n; j++)
      cin >> mat[i][j];
  }
  qs.resize(q);
  int i = 0;
  for(auto &x : qs) {
    cin >> x.x1 >> x.y1 >> x.x2 >> x.y2;
    x.ind = i++;
  }
  for(int step = 19; step >= 0; step--) {
    //cout << step << '\n';
    for(int i = 0; i < q; i++) {
      qs[i].val = sol[i] + (1 << step);
    }
    set();
  }
  for(int i = 0; i < q; i++) 
    cout << sol[i] << '\n';
  return 0;
}