Cod sursa(job #2629686)

Utilizator euyoTukanul euyo Data 22 iunie 2020 11:56:05
Problema Struti Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.53 kb
#include <fstream>

using namespace std;

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

const int LIM = 1000;
const int MAXD = 1 << 10;

int deq[MAXD];
int M[LIM][LIM];
int aux[LIM][LIM];
int maxa[LIM][LIM], mina[LIM][LIM], maxa1[LIM][LIM], mina1[LIM][LIM];
int n, m, b, e;

void pushFront( int x ) {
  b = (b - 1 + MAXD) % MAXD;
  deq[b] = x;
}
void popBack() {
  e = (e - 1 + MAXD) % MAXD;
}
void pushBack( int x ) {
  deq[e] = x;
  e = (e + 1) % MAXD;
}
void popFront() {
  b = (b + 1) % MAXD;
}
int qempty() {
  return (b == e);
}
void updateMax( int x ) {
  while ( !qempty() && deq[(e - 1 + MAXD) % MAXD] < x ) {
	popBack();
  }
}
void updateMin( int x ) {
  while ( !qempty() && deq[(e - 1 + MAXD) % MAXD] > x ) {
	popBack();
  }
}
void clear() {
  while ( !qempty() ) {
	popBack();
  }
}
void maxWl( int A[LIM][LIM], int B[LIM][LIM], int x, int y ) {
  int i, j;

  for ( i = 0; i < n; ++i ) {
    pushBack( A[i][0] );
	for ( j = 1; j < y; ++j ) {
	  updateMax( A[i][j] );
	  pushBack( A[i][j] );
	}
	B[i][y - 1] = deq[b];
	for ( j = y; j < m; ++j ) {
      updateMax( A[i][j] );
	  pushBack( A[i][j] );
	  if ( deq[b] == A[i][j - y] ) {
	    popFront();
	  } 
	  B[i][j] = deq[b];
	}
	clear();
  }
}
void maxWc( int A[LIM][LIM], int B[LIM][LIM], int x, int y ) {
  int i, j;

  for ( j = y - 1; j < m; ++j ) {
    pushBack( A[0][j] );
	for ( i = 1; i < x; ++i ) {
	  updateMax( A[i][j] );
	  pushBack( A[i][j] );
	}
	B[x - 1][j] = deq[b];
	for ( i = x; i < n; ++i ) {
      updateMax( A[i][j] );
	  pushBack( A[i][j] );
	  if ( deq[b] == A[i - x][j] ) {
	    popFront();
	  } 
	  B[i][j] = deq[b];
	}
	clear();
  }
}
void minWl( int A[LIM][LIM], int B[LIM][LIM], int x, int y ) {
  int i, j;

  for ( i = 0; i < n; ++i ) {
    pushBack( A[i][0] );
	for ( j = 1; j < y; ++j ) {
	  updateMin( A[i][j] );
	  pushBack( A[i][j] );
	}
	B[i][y - 1] = deq[b];
	for ( j = y; j < m; ++j ) {
      updateMin( A[i][j] );
	  pushBack( A[i][j] );
	  if ( deq[b] == A[i][j - y] ) {
	    popFront();
	  } 
	  B[i][j] = deq[b];
	}
	clear();
  }
}
void minWc( int A[LIM][LIM], int B[LIM][LIM], int x, int y ) {
  int i, j;

  for ( j = y - 1; j < m; ++j ) {
    pushBack( A[0][j] );
	for ( i = 1; i < x; ++i ) {
	  updateMin( A[i][j] );
	  pushBack( A[i][j] );
	}
	B[x - 1][j] = deq[b];
	for ( i = x; i < n; ++i ) {
      updateMin( A[i][j] );
	  pushBack( A[i][j] );
	  if ( deq[b] == A[i - x][j] ) {
	    popFront();
	  } 
	  B[i][j] = deq[b];
	}
	clear();
  }
}

void rangeMax( int x, int y ) {
  maxWl( M, aux, x, y );
  maxWc( aux, maxa, x, y );
  maxWl( M, aux, y, x );
  maxWc( aux, maxa1, y, x );
}
void rangeMin( int x, int y ) { 
  minWl( M, aux, x, y );
  minWc( aux, mina, x, y );
  minWl( M, aux, y, x );
  minWc( aux, mina1, y, x );
}

int main() {
  int p, i, j, minim, ap, x, y;
 
  fin >> n >> m >> p;
  for ( i = 0; i < n; ++i ) {
	for ( j = 0; j < m; ++j ) {
	  fin >> M[i][j];
	}
  }
  while ( p-- ) {
	fin >> x >> y;
    rangeMax( x, y );
	rangeMin( x, y );
	ap = 0;
	minim = 8000;
	for ( i = x - 1; i < n; ++i ) {
	  for ( j = y - 1; j < m; ++j ) {
		if ( maxa[i][j] - mina[i][j] < minim ) {
		  minim = maxa[i][j] - mina[i][j];
		  ap = 1;
		} else if ( maxa[i][j] - mina[i][j] == minim ) {
		  ++ap;
		}
	  }
    }
	if ( x != y ) {
	  for ( i = y - 1; i < n; ++i ) {
	    for ( j = x - 1; j < m; ++j ) {
		  if ( maxa1[i][j] - mina1[i][j] < minim ) { 
		    minim = maxa1[i][j] - mina1[i][j];
		    ap = 1;
		  } else if ( maxa1[i][j] - mina1[i][j] == minim ) {
		    ++ap;
		  }
	    }
	  }
	}
	fout << minim << " " << ap << "\n"; 
  }
  fin.close();
  fout.close();
  return 0;
}