Cod sursa(job #754073)

Utilizator darrenRares Buhai darren Data 31 mai 2012 14:06:55
Problema Struti Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.91 kb
#include <cctype> 
#include <fstream>
 
 using namespace std;
 
ifstream fin("struti.in");
ofstream fout("struti.out");
 
 char parse[1 << 16], *now;
 void verify()
 {
	 if (*now == 0)
	 {
		fin.get(parse, 1 << 16, '\0');
		now = parse;
	}
 }
 int get()
 {
	while (!isdigit(*now))
	{
		++now;
		verify();
	}
	
	int number = 0;
	while (isdigit(*now))
	{
		number *= 10, number += *now - '0';
		++now;
		verify();
	}
	
	return number;
 }
 
int N, M, P;
int A[1002][1002];
int Dmin[1002][2002], b1[1002];
int Dmax[1002][2002], b2[1002];
int Rmin[2002], B1;
int Rmax[2002], B2;
 
 int main()
 {
	now = parse;
	verify();
	
	N = get();
	M = get();
	P = get();
	
	for (int i = 1; i <= N; ++i)
		for (int j = 1; j <= M; ++j)
			A[i][j] = get();
	
	int L1, L2;
	for (int k = 1; k <= P; ++k)
	{
		L1 = get();
		L2 = get();
		int minnow = 1 << 30, total = 0;
		
		for (int i = 1; i <= M; ++i)
		{
			b1[i] = 1, b2[i] = 1;
			Dmin[i][0] = 0;
			Dmax[i][0] = 0;
		}
		for (int i = 1; i <= N; ++i)
		{
			for (int j = 1; j <= M; ++j)
			{
				if (b1[j] <= Dmin[j][0] && Dmin[j][b1[j]] <= i - L1)
					++b1[j];
				while (b1[j] <= Dmin[j][0] && A[i][j] <= A[Dmin[j][Dmin[j][0]]][j])
					--Dmin[j][0];
				Dmin[j][++Dmin[j][0]] = i;
				
				if (b2[j] <= Dmax[j][0] && Dmax[j][b2[j]] <= i - L1)
					++b2[j];
				while (b2[j] <= Dmax[j][0] && A[i][j] >= A[Dmax[j][Dmax[j][0]]][j])
					--Dmax[j][0];
				Dmax[j][++Dmax[j][0]] = i;
			}
			
			if (i < L1) continue;
			
			Rmin[0] = 0, B1 = 1;
			Rmax[0] = 0, B2 = 1;
			
			for (int j = 1; j <= M; ++j)
			{
				if (B1 <= Rmin[0] && Rmin[B1] <= j - L2)
					++B1;
				while (B1 <= Rmin[0] && A[Dmin[j][b1[j]]][j] <= A[Dmin[Rmin[Rmin[0]]][b1[Rmin[Rmin[0]]]]][Rmin[Rmin[0]]])
					--Rmin[0];
				Rmin[++Rmin[0]] = j;
				
				if (B2 <= Rmax[0] && Rmax[B2] <= j - L2)
					++B2;
				while (B2 <= Rmax[0] && A[Dmax[j][b2[j]]][j] >= A[Dmax[Rmax[Rmax[0]]][b2[Rmax[Rmax[0]]]]][Rmax[Rmax[0]]])
					--Rmax[0];
				Rmax[++Rmax[0]] = j;
				
				if (j >= L2)
				{
					if (A[Dmax[Rmax[B2]][b2[Rmax[B2]]]][Rmax[B2]] - A[Dmin[Rmin[B1]][b1[Rmin[B1]]]][Rmin[B1]] < minnow)
					{
						minnow = A[Dmax[Rmax[B2]][b2[Rmax[B2]]]][Rmax[B2]] - A[Dmin[Rmin[B1]][b1[Rmin[B1]]]][Rmin[B1]];
						total = 1;
					}
					else if (A[Dmax[Rmax[B2]][b2[Rmax[B2]]]][Rmax[B2]] - A[Dmin[Rmin[B1]][b1[Rmin[B1]]]][Rmin[B1]] == minnow)
						++total;
				}
			}
		}
		
		
		for (int i = 1; i <= M; ++i)
		{
			b1[i] = 1, b2[i] = 1;
			Dmin[i][0] = 0;
			Dmax[i][0] = 0;
		}
		for (int i = 1; i <= N; ++i)
		{
			for (int j = 1; j <= M; ++j)
			{
				if (b1[j] <= Dmin[j][0] && Dmin[j][b1[j]] <= i - L2)
					++b1[j];
				while (b1[j] <= Dmin[j][0] && A[i][j] <= A[Dmin[j][Dmin[j][0]]][j])
					--Dmin[j][0];
				Dmin[j][++Dmin[j][0]] = i;
				
				if (b2[j] <= Dmax[j][0] && Dmax[j][b2[j]] <= i - L2)
					++b2[j];
				while (b2[j] <= Dmax[j][0] && A[i][j] >= A[Dmax[j][Dmax[j][0]]][j])
					--Dmax[j][0];
				Dmax[j][++Dmax[j][0]] = i;
			}
			
			if (i < L2) continue;
			
			Rmin[0] = 0, B1 = 1;
			Rmax[0] = 0, B2 = 1;
			
			for (int j = 1; j <= M; ++j)
			{
				if (B1 <= Rmin[0] && Rmin[B1] <= j - L1)
					++B1;
				while (B1 <= Rmin[0] && A[Dmin[j][b1[j]]][j] <= A[Dmin[Rmin[Rmin[0]]][b1[Rmin[Rmin[0]]]]][Rmin[Rmin[0]]])
					--Rmin[0];
				Rmin[++Rmin[0]] = j;
				
				if (B2 <= Rmax[0] && Rmax[B2] <= j - L1)
					++B2;
				while (B2 <= Rmax[0] && A[Dmax[j][b2[j]]][j] >= A[Dmax[Rmax[Rmax[0]]][b2[Rmax[Rmax[0]]]]][Rmax[Rmax[0]]])
					--Rmax[0];
				Rmax[++Rmax[0]] = j;
				
				if (j >= L1)
				{
					if (A[Dmax[Rmax[B2]][b2[Rmax[B2]]]][Rmax[B2]] - A[Dmin[Rmin[B1]][b1[Rmin[B1]]]][Rmin[B1]] < minnow)
					{
						minnow = A[Dmax[Rmax[B2]][b2[Rmax[B2]]]][Rmax[B2]] - A[Dmin[Rmin[B1]][b1[Rmin[B1]]]][Rmin[B1]];
						total = 1;
					}
					else if (A[Dmax[Rmax[B2]][b2[Rmax[B2]]]][Rmax[B2]] - A[Dmin[Rmin[B1]][b1[Rmin[B1]]]][Rmin[B1]] == minnow)
						++total;
				}
			}
		}
		
		if (L1 == L2) total /= 2;
		fout << minnow << ' ' << total << '\n';
	}
	
	fin.close();
	fout.close();
 }