Cod sursa(job #169545)

Utilizator razvi9Jurca Razvan razvi9 Data 1 aprilie 2008 19:47:48
Problema Struti Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.58 kb
#include<cstdio>
#include<cstring>
const int lim=1001;
int n,m,p,x,y,a[lim][lim],min[lim][lim],max[lim][lim];
int stmin,drmin,D[2*lim],V[2*lim],d[2*lim],v[2*lim],drmax,stmax,_min,nr,i,j,aux;
inline void empty()
{
	stmin=1;
	drmin=0;
	stmax=1;
	drmax=0;
}
inline int getmin(int k)
{
	while(d[stmin]<k) stmin++;
	return v[stmin];
}
inline void addmin(int k,int val)
{
	while(drmin>=stmin && v[drmin]>=val) drmin--;
	d[++drmin]=k;
	v[drmin]=val;
}
inline int getmax(int k)
{
	while(D[stmax]<k) stmax++;
	return V[stmax];
}
inline void addmax(int k,int val)
{
	while(drmax>=stmax && V[drmax]<=val) drmax--;
	D[++drmax]=k;
	V[drmax]=val;
}
inline void add(int k,int val)
{
	addmin(k,val);
	addmax(k,val);
}
inline void dif(int x,int y)
{
	int i,j,dif;
	for(i=1;i<=n;i++){
		empty();
		for(j=1;j<x;j++)
			add(j,a[i][j]);
		for(j=1;j<=m-x+1;j++){
			add(j+x-1,a[i][j+x-1]);
			min[j][i]=getmin(j);
			max[j][i]=getmax(j);}}
	for(i=1;i<=m-x+1;i++){
		empty();
		for(j=1;j<y;j++){
			addmin(j,min[i][j]);
			addmax(j,max[i][j]);}
		for(j=1;j<=n-y+1;j++){
			addmin(j+y-1,min[i][j+y-1]);
			addmax(j+y-1,max[i][j+y-1]);
			dif=getmax(j)-getmin(j);
			if(dif<_min) _min=dif,nr=1;
			else
				if(dif==_min) nr++;
		}}
}
int main()
{
	freopen("struti.in","r",stdin);
	freopen("struti.out","w",stdout);
	scanf("%d %d %d",&n,&m,&p);
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			scanf("%d",&a[i][j]);
	for(;p;p--){
		scanf("%d %d",&x,&y);
		_min=(1<<31)-1;
		dif(x,y);
		if(x!=y) dif(y,x);
		printf("%d %d\n",_min,nr);
	}
	fclose(stdout);
	return 0;
}