Cod sursa(job #743290)

Utilizator alexandra_sanduSandu Alexandra Mihaela alexandra_sandu Data 3 mai 2012 21:11:20
Problema Struti Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.16 kb
#include <stdio.h>
#include <string.h>
#define NMAX (1 << 10)

int N, M, numSol;
int minL[NMAX][NMAX], maxL[NMAX][NMAX], minQ[NMAX], maxQ[NMAX], x[NMAX][NMAX];

int solve(int l, int L)
{
	int i, j, pmin, pmax, umin, umax, best = 1 << 30, nowMin, nowMax;
	
	numSol = 0;
	pmin = pmax = 1; umin = umax = 0;
	memset(minL, 0, sizeof(minL));
	memset(maxL, 0, sizeof(maxL));
	memset(minQ, 0, sizeof(minQ));
	memset(maxQ, 0, sizeof(maxQ));
	
	for (j = 1; j <= M; j ++)
	{
		for (i = 1; i <= N; i ++)
		{
			while (pmin <= umin && x[i][j] <= x[minQ[umin]][j])
				umin --;
			minQ[++ umin] = i;
			if (minQ[pmin] + l == i)
				pmin ++;
			minL[i][j] = x[minQ[pmin]][j];
		}
		
		pmin = 1; umin = 0;
	}
	
	for (j = 1; j <= M; j ++)
	{
		for (i = 1; i <= N; i ++)
		{
			while (pmax <= umax && x[i][j] >= x[maxQ[umax]][j])
				umax --;
			maxQ[++ umax] = i;
			if (maxQ[pmax] + l == i)
				pmax ++;
			maxL[i][j] = x[maxQ[pmax]][j];
		}
		
		pmax = 1; umax = 0;
	}
	
	for (i = l; i <= N; i ++)
	{
		for (j = 1; j <= M; j ++)
		{
			while (pmin <= umin && minL[i][j] <= minL[i][minQ[umin]])
				umin --;
			minQ[++ umin] = j;
			if (minQ[pmin] + L == j)
				pmin ++;
			nowMin = minL[i][minQ[pmin]];
			
			while (pmax <= umax && maxL[i][j] >= maxL[i][maxQ[umax]])
				umax --;
			maxQ[++ umax] = j;
			if (maxQ[pmax] + L == j)
				pmax ++;
			nowMax = maxL[i][maxQ[pmax]];
			
			if (j >= L)
			{
				if (nowMax - nowMin < best)
					best = nowMax - nowMin, numSol = 0;
				if (nowMax - nowMin == best)
					numSol ++;
			}
		}
		pmin = pmax = 1; umin = umax = 0;
	}	
	
	return best;
}

int main()
{
	int i, j, Q, L, l, sol, cntSol, now;
	
	freopen("struti.in", "r", stdin);
	freopen("struti.out", "w", stdout);
	
	scanf("%d%d%d", &N, &M, &Q);
	for (i = 1; i <= N; i ++)
		for (j = 1; j <= M; j ++)
			scanf("%d", &x[i][j]);
	
	while (Q --)
	{
		scanf("%d%d", &L, &l);
		
		sol = solve(L, l); cntSol = numSol;
		if (l != L)
		{
			now = solve(l, L);
			if (now < sol)
				sol = now, cntSol = numSol;
			else
			if (now == sol)
				cntSol += numSol;
		}
		
		printf("%d %d\n", sol, cntSol);
	}
	
	return 0;
}