Cod sursa(job #783566)

Utilizator danalex97Dan H Alexandru danalex97 Data 3 septembrie 2012 12:17:16
Problema Struti Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.36 kb
#include <fstream>
#include <deque>
#include <cstring>

using namespace std;

const int Nmax = 1011;
const int Cmax = 2000011;
const int oo = 1<<30;

char Str[Cmax];
int Act=0;

void Get( int& A )
{	A=0;
	while ( Str[Act]>'9' || Str[Act]<'0' ) ++Act;
	while ( Str[Act]>='0' && Str[Act]<='9' )
		A=A*10+Str[Act++]-'0';
}

ifstream F("struti.in"); 
ofstream G("struti.out"); 

int M,N,P,Dx,Dy;
int Co,Dif;

int A[Nmax][Nmax];
int Min[Nmax][Nmax];
int Max[Nmax][Nmax];

void Solve(int Dx,int Dy)
{
	for (register int i=1;i<=N;++i)
	{
		deque<int> Q,W;
		
		for (register int j=1;j<Dy;++j)
		{
			while ( Q.size() && A[i][Q.back()] >= A[i][j] ) Q.pop_back();
			while ( W.size() && A[i][W.back()] <= A[i][j] ) W.pop_back();
			Q.push_back( j );
			W.push_back( j );
		}
		
		for (register int j=Dy;j<=M;++j)
		{
			while ( Q.size() && Q.front()<=j-Dy ) Q.pop_front();
			while ( W.size() && W.front()<=j-Dy ) W.pop_front();
			while ( Q.size() && A[i][Q.back()] >= A[i][j] ) Q.pop_back();
			while ( W.size() && A[i][W.back()] <= A[i][j] ) W.pop_back();
			Q.push_back( j );
			W.push_back( j );
			
			Min[i][j]=A[i][Q.front()];
			Max[i][j]=A[i][W.front()];
		}
	}
	
	for (register int j=Dy;j<=M;j++)
    {
        deque<int> Q,W;
		
		for (register int i=1;i<Dx;++i)
		{
			while ( Q.size() && Min[Q.back()][j] >= Min[i][j] ) Q.pop_back();
			while ( W.size() && Max[W.back()][j] <= Max[i][j] ) W.pop_back();
			Q.push_back( i );
			W.push_back( i );
		}
		
        for (register int i=Dx;i<=N;++i)
        {
            while ( Q.size() && Q.front()<=i-Dx ) Q.pop_front();
            while ( W.size() && W.front()<=i-Dx ) W.pop_front();
            while ( Q.size() && Min[Q.back()][j] >= Min[i][j] ) Q.pop_back();
			while ( W.size() && Max[W.back()][j] <= Max[i][j] ) W.pop_back();
            Q.push_back( i );
            W.push_back( i );
            
			int Now = Max[W.front()][j] - Min[Q.front()][j];
			if ( Now<Dif ) Dif=Now, Co=0;
            if ( Now==Dif ) ++Co;
        }
    }
	
}

int main()
{
	F.getline(Str,Cmax,EOF);
	
	Get(M);Get(N);Get(P);
	for (int i=1;i<=N;++i)
		for (int j=1;j<=M;++j)
			Get( A[i][j] );
	
	for ( ;P;--P )
	{
		Get(Dx);Get(Dy);
		Dif=oo, Co=0;
		
		Solve(Dx,Dy);
		if ( Dx!=Dy ) 
			Solve(Dy,Dx);
		
		G<<Dif<<' '<<Co<<'\n';
	}
	
	F.close();
	G.close();
	return 0;
}