Cod sursa(job #2120243)

Utilizator AlexandruLuchianov1Alex Luchianov AlexandruLuchianov1 Data 2 februarie 2018 10:35:24
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.74 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <functional>
#include <algorithm>

using namespace std;

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

int const nmax = 300;
int const iplus[4] = {0 ,0 , 1 ,-1};
int const jplus[4] = {1 ,-1 ,0 ,0};
int n , q;

struct Number{
  int x;
  int y;
  int val;
  bool operator < (Number a) const{
    return val < a.val;
  }
  bool operator > (Number a) const{
    return val > a.val;
  }
};
vector< Number > v;
int v2[5 + nmax][5 + nmax];

int query[5 + nmax * nmax][4];
int result[5 + nmax * nmax];
int pos[5 + nmax * nmax];
bool compare(int x , int y){
  return result[x] > result[y];
}

int mult[5 + nmax][5 + nmax];
int multp[5 + nmax * nmax];
int x[5 + nmax * nmax];

int jumpm(int a){
  if(a == x[a]){
    return a;
  } else{
    x[a] = jumpm(x[a]);
    return x[a];
  }
}
void reunite(int gala , int galb){
  if(jumpm(gala) == jumpm(galb))
    return ;
  else{
    if(multp[gala] < multp[galb]){
      multp[galb] += multp[gala];
      multp[gala] = 0;
      x[x[gala]] = x[galb];
    } else{
      multp[gala] += multp[galb];
      multp[galb] = 0;
      x[x[galb]] = x[gala];
    }
  }
}
int last = 0;
bool valid(int x , int y){
  return (1 <= x && x <= n) && (1 <= y && y <= n);
}
void update(int val){
  while(last < v.size() && val <= v[last].val){
    int x = v[last].x;
    int y = v[last].y;
    for(int h = 0 ; h < 4 ;h++){
      int newx = x + iplus[h];
      int newy = y + jplus[h];
      if(valid(newx , newy) == 1 && val <= v2[newx][newy]){
        reunite(mult[x][y] , mult[newx][newy]);
      }
    }
    last++;
  }
}
void solve(int jump){
  for(int i = 1 ; i <= q ;i++){
    pos[i] = i;
  }
  sort(pos + 1 , pos + 1 + q , compare);
  for(int i = 1 ; i <= n ;i++){
    for(int j = 1 ; j <= n ;j++){
      int val = (i - 1) * n + j;
      mult[i][j] = val;
      multp[val] = 1;
      x[val] = val;
    }
  }
  last = 0;
  for(int i = 1 ; i <= q ;i++){
    update(result[pos[i]] + jump);
    int x = query[pos[i]][0];
    int y = query[pos[i]][1];
    int x2 = query[pos[i]][2];
    int y2 = query[pos[i]][3];
    if(jumpm(mult[x][y]) == jumpm(mult[x2][y2])){
      result[pos[i]] += jump;
    }
  }
}
int main()
{
  in>>n>>q;
  for(int i = 1 ; i <= n ;i++){
    for(int j = 1 ; j <= n ;j++){
      int a;
      in>>a;
      v2[i][j] = a;
      v.push_back({i , j , a});
    }
  }
  sort(v.begin() , v.end() ,greater <Number>() );
  for(int i = 1 ; i <= q ;i++){
    in>>query[i][0]>>query[i][1]>>query[i][2]>>query[i][3];
  }
  for(int jump = (1 << 20) ;1 <= jump ;jump /= 2){
    solve(jump);
  }
  for(int i = 1 ; i <= q ;i++){
    out<<result[i]<<'\n';
  }
  return 0;
}