Cod sursa(job #343691)

Utilizator cosmin79Carabet Cosmin Andrei cosmin79 Data 26 august 2009 21:13:08
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.76 kb
#include <stdio.h>
#include <string.h>
#define N 1005
int v[N][N];
int m,n,p,st,dr;
int r,inc,sf,inc2,sf2;
int mat[N][N][2],mat2[N][N][2];
int op[N],op2[N],deq[N],deq2[N],rez,sol;
int limita[3];
void read()
{
	scanf("%d%d%d",&m,&n,&p);
	int i,j;
	for (i=1; i<=m; i++)
		for (j=1; j<=n; j++)
			scanf("%d",&v[i][j]);
}
void capat_min(int i,int tip)
{
	if (i-deq[inc]>=limita[tip])
		inc++;
}
void actualizare_min(int i,int tip)
{
	while (inc!=sf && op[i]<=op[deq[sf-1]])
		--sf;
	deq[sf++]=i;
}
void actualizare_max(int i,int tip)
{
	while (inc2!=sf2 && op[i]>=op[deq2[sf2-1]])
		--sf2;
	deq2[sf2++]=i;
}
void capat_max(int i,int tip)
{
	if (i-deq2[inc2]>=limita[tip])
		inc2++;
}
void coloana1()
{
	int i,j;
	for (j=1; j<=n; j++)
	{
		inc=0;
		sf=0;
		inc2=0;
		sf2=0;
		r=0;
		for (i=1; i<=m; i++)
			op[i]=v[i][j];
		for (i=1; i<=st; i++)
		{
			actualizare_min(i,1);
			actualizare_max(i,1);
		}
		mat[++r][j][0]=op[deq[inc]];
		mat[r][j][1]=op[deq2[inc2]];
		for (i=st+1; i<=m; i++)
		{
			actualizare_min(i,1);
			capat_min(i,1);
			mat[++r][j][0]=op[deq[inc]];
			actualizare_max(i,1);
			capat_max(i,1);
			mat[r][j][1]=op[deq2[inc2]];
		}
	}
}
void coloana2()
{
	int i,j;
	for (j=1; j<=n; j++)
	{
		inc=0;
		sf=0;
		inc2=0;
		sf2=0;
		r=0;
		for (i=1; i<=m; i++)
			op[i]=v[i][j];
		for (i=1; i<=dr; i++)
		{
			actualizare_min(i,2);
			actualizare_max(i,2);
		}
		mat2[++r][j][0]=op[deq[inc]];
		mat2[r][j][1]=op[deq2[inc2]];
		for (i=dr+1; i<=m; i++)
		{
			actualizare_min(i,2);
			capat_min(i,2);
			mat2[++r][j][0]=op[deq[inc]];
			actualizare_max(i,2);
			capat_max(i,2);
			mat2[r][j][1]=op[deq2[inc2]];
		}
	}
}
void cap_min(int i,int tip)
{
	if (i-deq[inc]>=limita[tip])
		inc++;
}
void act_min(int i,int tip)
{
	while (inc!=sf && op[i]<=op[deq[sf-1]])
		--sf;
	deq[sf++]=i;
}
void act_max(int i,int tip)
{
	while (inc2!=sf2 && op2[i]>=op2[deq2[sf2-1]])
		--sf2;
	deq2[sf2++]=i;
}
void cap_max(int i,int tip)
{
	if (i-deq2[inc2]>=limita[tip])
		inc2++;
}
void linie1()
{
	int i,j;
	for (i=1; i<=m-st+1; i++)
	{
		inc=0;
		sf=0;
		inc2=0;
		sf2=0;
		r=0;
		for (j=1; j<=n; j++)
		{
			op[j]=mat[i][j][0];
			op2[j]=mat[i][j][1];
		}
		for (j=1; j<=dr; j++)
		{
			act_min(j,2);
			act_max(j,2);
		}
		if (op2[deq2[inc2]]-op[deq[inc]]==rez)
			sol++;
		if (op2[deq2[inc2]]-op[deq[inc]]<rez)
		{
			rez=op2[deq2[inc2]]-op[deq[inc]];
			sol=1;
		}
		for (j=dr+1; j<=n; j++)
		{
			act_min(j,2);
			cap_min(j,2);
			act_max(j,2);
			cap_max(j,2);
			if (op2[deq2[inc2]]-op[deq[inc]]==rez)
				sol++;
			if (op2[deq2[inc2]]-op[deq[inc]]<rez)
			{
				rez=op2[deq2[inc2]]-op[deq[inc]];
				sol=1;
			}
		}
	}
}
void linie2()
{
	int i,j;
	for (i=1; i<=m-dr+1; i++)
	{
		inc=0;
		sf=0;
		inc2=0;
		sf2=0;
		r=0;
		for (j=1; j<=n; j++)
		{
			op[j]=mat2[i][j][0];
			op2[j]=mat2[i][j][1];
		}
		for (j=1; j<=st; j++)
		{
			act_min(j,1);
			act_max(j,1);
		}
		if (op2[deq2[inc2]]-op[deq[inc]]==rez)
			sol++;
		if (op2[deq2[inc2]]-op[deq[inc]]<rez)
		{
			rez=op2[deq2[inc2]]-op[deq[inc]];
			sol=1;
		}
		for (j=st+1; j<=n; j++)
		{
			act_min(j,1);
			cap_min(j,1);
			act_max(j,1);
			cap_max(j,1);
			if (op2[deq2[inc2]]-op[deq[inc]]==rez)
				sol++;
			if (op2[deq2[inc2]]-op[deq[inc]]<rez)
			{
				rez=op2[deq2[inc2]]-op[deq[inc]];
				sol=1;
			}
		}
	}
}
void query()
{
	int i;
	for (i=1; i<=p; i++)
	{
		scanf("%d%d",&st,&dr);
		rez=1<<20;
		sol=0;
		limita[1]=st;
		limita[2]=dr;
		coloana1();
		coloana2();
		linie1();
		if (st!=dr)
			linie2();
		printf("%d %d\n",rez,sol);
	}
}
int main()
{
	freopen("struti.in","r",stdin);
	freopen("struti.out","w",stdout);
	read();
	query();
	return 0;
}