Cod sursa(job #851683)

Utilizator crushackPopescu Silviu crushack Data 10 ianuarie 2013 12:11:57
Problema Struti Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.97 kb
#include <stdio.h>
#include <algorithm>
#define NMax 1010
#define LNMax 11
using namespace std;

const char IN[]="struti.in",OUT[]="struti.out";

int N,M,P;
int lg[NMax];
int v[NMax][NMax];
short rmq[NMax][NMax][LNMax][LNMax], rmq2[NMax][NMax][LNMax][LNMax];

void range()
{
	int i,j,k,l;
	for (i=1;i<=N;++i) for (j=1;j<=M;++j) rmq[i][j][0][0]=v[i][j],rmq2[i][j][0][0]=v[i][j];
	
	for (k=0;(1<<k)<=N;++k)
	{
		if (k!=0)
		{
			for (i=1;i<=N;++i)
				for (j=1;j<=M;++j)
					rmq[i][j][k][0]=max(rmq[i][j][k-1][0],rmq[i+(1<<k-1)][j][k-1][0]),
					rmq2[i][j][k][0]=min(rmq2[i][j][k-1][0],rmq2[i+(1<<k-1)][j][k-1][0]);
		}
		for (l=1;(1<<l)<=M;++l)
		{
			
			for (i=1;i<=N;++i)
				for (j=1;j<=M;++j)
					rmq[i][j][k][l]=max(rmq[i][j][k][l-1],rmq[i][j+(1<<l-1)][k][l-1]),
					rmq2[i][j][k][l]=min(rmq2[i][j][k][l-1],rmq2[i][j+(1<<l-1)][k][l-1]);
			
		}
	}
}

int getmax(int x,int y,int x2,int y2)
{
	int lx=lg[x2-x+1],ly=lg[y2-y+1];
	return max(rmq[x][y][lx][ly],max(rmq[x2-(1<<lx)+1][y][lx][ly],max(rmq[x][y2-(1<<ly)+1][lx][ly],rmq[x2-(1<<lx)+1][y2-(1<<ly)+1][lx][ly])));
}

int getmin(int x,int y,int x2,int y2)
{
	int lx=lg[x2-x+1],ly=lg[y2-y+1];
	return min(rmq2[x][y][lx][ly],min(rmq2[x2-(1<<lx)+1][y][lx][ly],min(rmq2[x][y2-(1<<ly)+1][lx][ly],rmq2[x2-(1<<lx)+1][y2-(1<<ly)+1][lx][ly])));
}

void query(int dx,int dy,int &min,int &ct)
{
	int i,j;
	for (i=dx;i<=N;++i)
		for (j=dy;j<=M;++j)
		{
			int r=getmax(i-dx+1,j-dy+1,i,j)-getmin(i-dx+1,j-dy+1,i,j);
			if (r<min) min=r,ct=1;
			else if (r==min) ++ct;
		}
}

int main()
{
	int i,j,dx,dy,min,ct;
	freopen(IN,"r",stdin);
	scanf("%d%d%d",&N,&M,&P);
	for (i=1;i<=N;++i) for (j=1;j<=M;++j) scanf("%d",v[i]+j);
	
	range();
	for (i=2;i<=N || i<=M;++i) lg[i]=1+lg[i/2];
	
	freopen(OUT,"w",stdout);
	while (P--)
	{
		scanf("%d%d",&dx,&dy);
		min=(1<<31)-1,ct=0;
		query(dx,dy,min,ct);
		if (dx!=dy) query(dy,dx,min,ct);
		printf("%d %d\n",min,ct);
	}
	fclose(stdout);
	
	return 0;
}