Cod sursa(job #2681124)

Utilizator andreic06Andrei Calota andreic06 Data 4 decembrie 2020 23:48:22
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.83 kb
#include <iostream>
#include <fstream>
#include <algorithm>

using namespace std;
const int N = 3e2;
const int Q = 2e4;
const int VEC = 4;
const int MAX_BIT = ( 1 << 20 );

struct Query {
      int start_x, start_y;
      int stop_x, stop_y;
      int initial_ordinal, ans;

      bool operator < ( const Query &other ) const {
          return ans > other.ans;
      }
} query[Q + 1];

struct matrix {
      int line, col, x;
      bool operator < ( const matrix &other ) const {
          return x < other.x;
      }
} liniar_matrix[N*N + 1];
int value[N*N + 1];

int sef[N*N + 1];
int dl[] = { -1, 0, 1,  0 };
int dc[] = {  0, 1, 0, -1 };

int n, m;

static inline int define_point ( int x, int y ) {
      return n * ( x - 1 ) + y;
}


int sef_suprem ( int x ) {
   if ( sef[x] == x )
     return x;
   return sef[x] = sef_suprem ( sef[x] );
}

bool in_matrix ( int x, int y ) {
    if ( x && y && x <= n && y <= n )
      return true;
    return false;
}

void union_xy ( int x, int y ) {
    int sef_x = sef_suprem ( x );
    int sef_y = sef_suprem ( y );

    sef[sef_y] = sef_x;
}

bool last_comp ( Query A, Query B ) {
    return A.initial_ordinal < B.initial_ordinal;
}

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

int main()
{
   fin >> n >> m;
   for ( int i = 1; i <= n; i ++ ) {
      for ( int j = 1; j <= n; j ++ ) {
         int x; fin >> x;
         int pos = define_point ( i, j );
         liniar_matrix[pos] = {i, j, x};
         value[pos] = x;
      }
   }

   for ( int i = 1; i <= m; i ++ ) {
      int x1, y1; int x2, y2;

      fin >> x1 >> y1;
      fin >> x2 >> y2;

      query[i] = { x1, y1, x2, y2, i, 0 };
   }

   sort ( liniar_matrix + 1, liniar_matrix + n * n + 1 );

   for ( int bit = MAX_BIT; bit; bit >>= 1 ) {
      sort ( query + 1, query + m + 1 );

      for ( int i = 1; i <= n * n; i ++ )
         sef[i] = i;

      int k = n * n;
      for ( int q = 1; q <= m; q ++ ) {
         int test_value = query[q].ans + bit;
         while ( k && liniar_matrix[k].x >= test_value ) {
            for ( int p = 0; p < VEC; p ++ ) {
               int new_line = liniar_matrix[k].line + dl[p];
               int new_col = liniar_matrix[k].col + dc[p];
               if ( in_matrix ( new_line, new_col ) == true ) {
                 int point = define_point ( new_line, new_col );
                 if ( value[point] >= test_value )
                   union_xy ( define_point ( liniar_matrix[k].line, liniar_matrix[k].col ), point );
               }
            }

            k --;
         }
         if ( sef_suprem ( define_point ( query[q].start_x, query[q].start_y ) ) == sef_suprem ( define_point ( query[q].stop_x, query[q].stop_y ) ) )
           query[q].ans += bit;
      }
   }

   sort ( query + 1, query + m + 1, last_comp );
   for ( int i = 1; i <= m; i ++ )
      fout << query[i].ans << '\n';


    return 0;
}