Cod sursa(job #598440)

Utilizator Catah15Catalin Haidau Catah15 Data 25 iunie 2011 19:01:24
Problema Struti Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.74 kb
#include <iostream>
#include <deque>
#include <cmath>

using namespace std;

#define maxN 1005
#define inf (1 << 30)

int Dmin[maxN], Dmax[maxN];
int A[maxN][maxN];
int minim[maxN][maxN], maxim[maxN][maxN];
int Fminim[maxN][maxN], Fmaxim[maxN][maxN];


int main()
{
	freopen ("struti.in", "r", stdin);
	freopen ("struti.out", "w", stdout);
	
	int N, M, P;
	
	scanf ("%d %d %d", &N, &M, &P);
	
	for (int i = 1; i <= N; ++ i)
		for (int j = 1; j <= M; ++ j)
			scanf ("%d", &A[i][j]);
	
	
	while (P --)
	{
		int Dx, Dy;
		
		scanf ("%d %d", &Dx, &Dy);
		
		// Dx * Dy
		
		for (int i = 1; i <= N; ++ i)
		{
			int stmin = 1, drmin = 0;
			int stmax = 1, drmax = 0;
			
			for (int j = 1; j <= M; ++ j)
			{
				if ( stmin <= drmin && Dmin[stmin] <= j - Dx ) ++ stmin;
				if ( stmax <= drmax && Dmax[stmax] <= j - Dx ) ++ stmax;	
				
				while ( stmin <= drmin && A[i][Dmin[drmin]] > A[i][j] ) -- drmin;
				while ( stmax <= drmax && A[i][Dmax[drmax]] < A[i][j] ) -- drmax;
				
				Dmin[++ drmin] = j;
				Dmax[++ drmax] = j;
				
				if (j >= Dx)
				{
					minim[i][j] = A[i][Dmin[stmin]];
					maxim[i][j] = A[i][Dmax[stmax]];
				}
			}
		}
		
		for (int j = Dx; j <= M; ++ j)
		{
			int stmin = 1, drmin = 0;
			int stmax = 1, drmax = 0;
			
			for (int i = 1; i <= N; ++ i)
			{
				if ( stmin <= drmin && Dmin[stmin] <= i - Dy ) ++ stmin;
				if ( stmax <= drmax && Dmax[stmax] <= i - Dy ) ++ stmax;	
				
				while ( stmin <= drmin && minim[Dmin[drmin]][j] > minim[i][j] ) -- drmin;
				while ( stmax <= drmax && maxim[Dmax[drmax]][j] < maxim[i][j] ) -- drmax;
				
				Dmin[++ drmin] = i;
				Dmax[++ drmax] = i;
				
				if (i >= Dy)
				{
					Fminim[i][j] = minim[Dmin[stmin]][j];
					Fmaxim[i][j] = maxim[Dmax[stmax]][j];
				}
			}
		}
		
		int K = 0, sol = inf;
		
		for (int i = Dy; i <= N; ++ i)
			for (int j = Dx; j <= M; ++ j)
				if ( abs (Fmaxim[i][j] - Fminim[i][j] < sol) )
				{
					sol = abs (Fmaxim[i][j] - Fminim[i][j]);
					K = 1;
				}
				else if ( abs (Fmaxim[i][j] - Fminim[i][j] == sol) ) ++ K;
		
		
		
		// Dy * Dx
		
		if (Dx != Dy)
		{
			swap (Dx, Dy);
			
			for (int i = 1; i <= N; ++ i)
			{
				int stmin = 1, drmin = 0;
				int stmax = 1, drmax = 0;
				
				for (int j = 1; j <= M; ++ j)
				{
					if ( stmin <= drmin && Dmin[stmin] <= j - Dx ) ++ stmin;
					if ( stmax <= drmax && Dmax[stmax] <= j - Dx ) ++ stmax;	
					
					while ( stmin <= drmin && A[i][Dmin[drmin]] > A[i][j] ) -- drmin;
					while ( stmax <= drmax && A[i][Dmax[drmax]] < A[i][j] ) -- drmax;
					
					Dmin[++ drmin] = j;
					Dmax[++ drmax] = j;
					
					if (j >= Dx)
					{
						minim[i][j] = A[i][Dmin[stmin]];
						maxim[i][j] = A[i][Dmax[stmax]];
					}
				}
			}
			
			for (int j = Dx; j <= M; ++ j)
			{
				int stmin = 1, drmin = 0;
				int stmax = 1, drmax = 0;
				
				for (int i = 1; i <= N; ++ i)
				{
					if ( stmin <= drmin && Dmin[stmin] <= i - Dy ) ++ stmin;
					if ( stmax <= drmax && Dmax[stmax] <= i - Dy ) ++ stmax;	
					
					while ( stmin <= drmin && minim[Dmin[drmin]][j] > minim[i][j] ) -- drmin;
					while ( stmax <= drmax && maxim[Dmax[drmax]][j] < maxim[i][j] ) -- drmax;
					
					Dmin[++ drmin] = i;
					Dmax[++ drmax] = i;
					
					if (i >= Dy)
					{
						Fminim[i][j] = minim[Dmin[stmin]][j];
						Fmaxim[i][j] = maxim[Dmax[stmax]][j];
					}
				}
			}
			
			
			for (int i = Dy; i <= N; ++ i)
				for (int j = Dx; j <= M; ++ j)
					if ( abs (Fmaxim[i][j] - Fminim[i][j] < sol) )
					{
						sol = abs (Fmaxim[i][j] - Fminim[i][j]);
						K = 1;
					}
					else if ( abs (Fmaxim[i][j] - Fminim[i][j] == sol) ) ++ K;
			
		}
		
		
		printf ("%d %d \n", sol, K);
	}
	
	
	return 0;
}