Cod sursa(job #21830)

Utilizator testTest User test Data 24 februarie 2007 15:32:35
Problema Struti Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.65 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], max[MAXN][MAXN];
short vd[MAXN][MAXN], vdl[MAXN], vdr[MAXN], vdp[MAXN][MAXN];		//vertical deques
short hd[MAXN], hdl, hdr, hdp[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[i], vdl[i], vdr[i], vdp[i] );
	for (i = 0; i < a - 1; i++)
		for (j = 0; j < M; j++)
			addmax( vd[j], vdl[j], vdr[j], vdp[j], x[i][j], i, a );

	for (i = a - 1; i < N; i++)
	{
		init( hd, hdl, hdr, hdp );
		for (j = 0; j < M; j++)
		{
			addmax( vd[j], vdl[j], vdr[j], vdp[j], x[i][j], i, a );
			
			addmax( hd, hdl, hdr, hdp, top( vd[j], vdl[j] ), j, b );
	
			max[i][j] = top(hd, hdl);
		}
	}

	for (i = 0; i < M; i++)
		init( vd[i], vdl[i], vdr[i], vdp[i] );
	for (i = 0; i < a - 1; i++)
		for (j = 0; j < M; j++)
			addmin( vd[j], vdl[j], vdr[j], vdp[j], x[i][j], i, a );

	for (i = a - 1; i < N; i++)
	{
		init( hd, hdl, hdr, hdp );
		for (j = 0; j < M; j++)
		{
			addmin( vd[j], vdl[j], vdr[j], vdp[j], x[i][j], i, a );
			
			addmin( hd, hdl, hdr, hdp, top( vd[j], vdl[j] ), j, b );
	
			if (j >= b - 1)
			{
				int val = max[i][j] - top(hd, hdl);
				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;
}