Cod sursa(job #601717)

Utilizator Catah15Catalin Haidau Catah15 Data 7 iulie 2011 15:56:38
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.4 kb
#include <fstream>

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 main()
{
	ifstream f("struti.in");
	ofstream g("struti.out");
	
	int N, M, P;
	
	f >> N >> M >> P;
	
	for (int i = 1; i <= N; ++ i)
		for (int j = 1; j <= M; ++ j)
			f >> A[i][j];
	
	
	while (P --)
	{
		int Dx, Dy;
		
		f >> 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]];
				}
			}
		}
		
		int K = 0, sol = inf;
		
		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)
				{
					int Fminim = minim[Dmin[stmin]][j];
					int Fmaxim = maxim[Dmax[stmax]][j];
					
					if ( (Fmaxim - Fminim < sol) )
					{
						sol = (Fmaxim - Fminim);
						K = 1;
					}
					else if ( (Fmaxim - Fminim == sol) ) ++ K;
				}
			}
		}
		
		
		// Dy * Dx
		
		if (Dx != Dy)
		{
			int aux = Dx;
			Dx = Dy;
			Dy = aux;
			
			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)
					{
						int Fminim = minim[Dmin[stmin]][j];
						int Fmaxim = maxim[Dmax[stmax]][j];
						
						if ( (Fmaxim - Fminim < sol) )
						{
							sol = (Fmaxim - Fminim);
							K = 1;
						}
						else if ( (Fmaxim - Fminim == sol) ) ++ K;
					}
				}
			}
		}
		
		
		g << sol << " " << K << '\n';
	}
	
	
	return 0;
}