Pagini recente » Cod sursa (job #88107) | Cod sursa (job #2745801) | Cod sursa (job #1068630) | Cod sursa (job #1086107) | Cod sursa (job #1068601)
#include <iostream>
#include <fstream>
#include <deque>
using namespace std;
const int Nmax = 1001;
int N, M, P, answer, counts;
int A[Nmax][Nmax];
deque <int> min_col[Nmax];
deque <int> max_col[Nmax];
deque <int> 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++;
}
}
}
}
}
}
}
int main()
{
ifstream f("struti.in");
ofstream g("struti.out");
f >> N >> M >> P;
for ( int i = 1; i <= N; ++i )
{
for ( int j = 1; j <= M; ++j )
{
f >> A[i][j];
}
}
for ( int i = 1, dx, dy; i <= P; ++i )
{
answer = 10000;
counts = 0;
f >> dx >> dy;
query( dx, dy );
if ( dx != dy )
query( dy, dx );
g << answer << " " << counts << endl;
}
return 0;
}