Cod sursa(job #23781)

Utilizator bogdan2412Bogdan-Cristian Tataroiu bogdan2412 Data 1 martie 2007 13:32:44
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.68 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[MAXN][MAXN], vdl[MAXN], vdr[MAXN], vdp[MAXN][MAXN];		//vertical deques
short hd[MAXN], hdl, hdr, hdp[MAXN];					//horizontal deques

short Sol[MAXN][MAXN];

inline void query( int a, int b, int &MIN, int &MINnr )
{
	int i, j;
	for (i = 0; i < M; i++)
		init( vd[i], vdl[i], vdr[i], vd[i] );
	for (j = 0; j < M; j++)
		for (i = 0; i < a - 1; i++)
			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 );
	
			Sol[i][j] = top( hd, hdl );
		}
	}

	for (i = 0; i < M; i++)
		init( vd[i], vdl[i], vdr[i], vd[i] );
	for (j = 0; j < M; j++)
		for (i = 0; i < a - 1; i++)
			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 );

			Sol[i][j] -= top( hd, hdl );
		}
	}


	MIN = 0x3f3f3f3f; MINnr = 0;
	for (i = a - 1; i < N; i++)
		for (j = b - 1; j < M; j++)
		{
			int k = Sol[i][j];
			if (k < MIN)
			{
				MIN = k;
				MINnr = 1;
			}
			else
				if (k == MIN)
					MINnr++;
		}
}

char tmp[MAXN * 5];

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

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

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

			x[j][i] = 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;
}