Pagini recente » Cod sursa (job #1166938) | Cod sursa (job #1314414) | Cod sursa (job #1999052) | Cod sursa (job #1794688) | Cod sursa (job #1068629)
#include <iostream>
#include <fstream>
#include <deque>
using namespace std;
const int Nmax = 1001;
struct DEQUE
{
int frnt;
int bck;
int d[Nmax];
void clear()
{
frnt = 1;
bck = 0;
}
int size()
{
if ( frnt <= bck )
return bck - frnt + 1;
else
return 0;
}
int back()
{
return d[ bck ];
}
int front()
{
return d[ frnt ];
}
void pop_back()
{
bck--;
}
void pop_front()
{
frnt++;
}
void push_back( int value )
{
d[ ++bck ] = value;
}
};
int N, M, P, answer, counts;
int A[Nmax][Nmax];
DEQUE min_col[Nmax];
DEQUE max_col[Nmax];
DEQUE min_lin, max_lin;
void query( int dx, int dy )
{
for ( int i = 1; i <= M; ++i )
{
min_col[i].clear();
max_col[i].clear();
}
for ( int i = 1; i <= N; ++i )
{
min_lin.clear();
max_lin.clear();
for ( int j = 1; j <= M; ++j )
{
/// minimul de pe coloana j
while ( min_col[j].size() && A[ min_col[j].back() ][j] >= A[i][j] ) min_col[j].pop_back();
while ( min_col[j].size() && min_col[j].front() <= i - dx ) min_col[j].pop_front();
min_col[j].push_back ( i );
/// maximul de pe coloana j
while ( max_col[j].size() && A[ max_col[j].back() ][j] <= A[i][j] ) max_col[j].pop_back();
while ( max_col[j].size() && max_col[j].front() <= i - dx ) max_col[j].pop_front();
max_col[j].push_back( i );
if ( i >= dx )
{
int min_i = min_col[j].front();
int max_i = max_col[j].front();
/// minimul din dreptunghiul [i,j]->[i+dx-1,j+dy-1]
while ( min_lin.size() && A[ min_col[ min_lin.back() ].front() ][ min_lin.back() ] >= A[ min_i ][j] ) min_lin.pop_back();
while ( min_lin.size() && min_lin.front() <= j - dy ) min_lin.pop_front();
min_lin.push_back( j );
/// maximul din dreptunghiul [i,j]->[i+dx-1,j+dy-1]
while ( max_lin.size() && A[ max_col[ max_lin.back() ].front() ][ max_lin.back() ] <= A[ max_i ][j] ) max_lin.pop_back();
while ( max_lin.size() && max_lin.front() <= j - dy ) max_lin.pop_front();
max_lin.push_back( j );
if ( j >= dy )
{
int min_l, max_l, min_c, max_c;
min_c = min_lin.front();
max_c = max_lin.front();
min_l = min_col[ min_c ].front();
max_l = max_col[ max_c ].front();
int diff = A[ max_l ][ max_c ] - A[ min_l ][ min_c ];
if ( diff < answer )
{
answer = diff;
counts = 1;
}
else
{
if ( diff == answer )
{
counts++;
}
}
}
}
}
}
}
const int DIM_BUFF = ( 1 << 20 );
char buffer[DIM_BUFF];
int position = DIM_BUFF;
char GetChar()
{
if ( position == DIM_BUFF )
{
fread( buffer, 1, DIM_BUFF, stdin );
position = 0;
}
return buffer[ position++ ];
}
int rd()
{
int nr = 0;
char c;
do
{
c = GetChar();
} while ( !isdigit( c ) );
do
{
nr = nr * 10 + ( c - '0' );
c = GetChar();
} while ( isdigit( c ) );
return nr;
}
int main()
{
freopen("struti.in", "r", stdin);
freopen("struti.out", "w", stdout);
N = rd(); M = rd(); P = rd();
for ( int i = 1; i <= N; ++i )
{
for ( int j = 1; j <= M; ++j )
{
A[i][j] = rd();
}
}
for ( int i = 1, dx, dy; i <= P; ++i )
{
answer = 10000;
counts = 0;
dx = rd(); dy = rd();
query( dx, dy );
if ( dx != dy )
query( dy, dx );
printf("%d %d\n", answer, counts);
}
return 0;
}