Cod sursa(job #21831)

Utilizator testTest User test Data 24 februarie 2007 15:33:08
Problema Struti Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.63 kb
#include <stdio.h>

inline void init( short d[], short &dl, short &dr, short poz[] ) { dl = 0; dr = -1; }

inline void addmax( short d[], short &dl, short &dr, short p[], short val, short poz, short L )
{
	while (dr >= dl && d[dr] <= val) dr--;
	if (dl <= dr && poz - p[dl] >= L) dl++;
	d[++dr] = val;
	p[dr] = poz;
}

inline void addmin( short d[], short &dl, short &dr, short p[], short val, short poz, short L )
{
	while (dr >= dl && d[dr] >= val) dr--;
	if (dl <= dr && poz - p[dl] >= L) dl++;
	d[++dr] = val;
	p[dr] = poz;
}

inline short top( short d[], short dl ) { return d[dl]; }

#define MAXN 1005

int M, N, P;
short x[MAXN][MAXN];
short vd[2][MAXN][MAXN], vdl[2][MAXN], vdr[2][MAXN], vdp[2][MAXN][MAXN];		//vertical deques
short hd[2][MAXN], hdl[2], hdr[2], hdp[2][MAXN];					//horizontal deques

inline void query( int a, int b, int &MIN, int &MINnr )
{
	int i, j;
       	MIN = 0x3f3f3f3f; MINnr = 0;
	for (i = 0; i < M; i++)
	{
		init( vd[0][i], vdl[0][i], vdr[0][i], vdp[0][i] );
		init( vd[1][i], vdl[1][i], vdr[1][i], vdp[1][i] );
	}
	for (i = 0; i < a - 1; i++)
		for (j = 0; j < M; j++)
		{
			addmax( vd[0][j], vdl[0][j], vdr[0][j], vdp[0][j], x[i][j], i, a );
			addmin( vd[1][j], vdl[1][j], vdr[1][j], vdp[1][j], x[i][j], i, a );
		}

	for (i = a - 1; i < N; i++)
	{
		init( hd[0], hdl[0], hdr[0], hdp[0] );
		init( hd[1], hdl[1], hdr[1], hdp[1] );
		for (j = 0; j < M; j++)
		{
			addmax( vd[0][j], vdl[0][j], vdr[0][j], vdp[0][j], x[i][j], i, a );
			addmin( vd[1][j], vdl[1][j], vdr[1][j], vdp[1][j], x[i][j], i, a );
			
			addmax( hd[0], hdl[0], hdr[0], hdp[0], top( vd[0][j], vdl[0][j] ), j, b );
			addmin( hd[1], hdl[1], hdr[1], hdp[1], top( vd[1][j], vdl[1][j] ), j, b );
	
			if (j >= b - 1)
			{
				int val = top(hd[0], hdl[0]) - top(hd[1], hdl[1]);
				if (val < MIN)
				{
					MIN = val;
					MINnr = 1;
				}
				else
					if (val == MIN)
						MINnr++;
			}
		}
	}
}

char tmp[MAXN * 5];

int main()
{
	freopen("struti.in", "rt", stdin);
	freopen("struti.out", "wt", stdout);

	scanf(" %d %d %d ", &N, &M, &P);

	int i, j;
	for (i = 0; i < N; i++)
	{
		fgets(tmp, MAXN * 5, stdin);
		char *p = tmp;
		for (j = 0; j < M; j++)
		{
			for (; '0' > *p || *p > '9'; p++);
			short k = 0;
			for (; '0' <= *p && *p <= '9'; p++)
				k = k * 10 + *p - '0';

			x[i][j] = k;
		}
	}

	for (i = 0; i < P; i++)
	{
		int a, b, MIN, MINnr, MIN2, MINnr2;
		scanf("%d %d", &a, &b);
		if (a == b)
			query(a, b, MIN, MINnr);
		else
		{
			query(a, b, MIN, MINnr);
			query(b, a, MIN2, MINnr2);

			if (MIN == MIN2)
				MINnr += MINnr2;
			else
				if (MIN > MIN2)
				{
					MIN = MIN2;
					MINnr = MINnr2;
				}
		}
		printf("%d %d\n", MIN, MINnr);
	}

	return 0;
}