Cod sursa(job #778331)

Utilizator maritimCristian Lambru maritim Data 14 august 2012 15:38:40
Problema Struti Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.74 kb
#include<stdio.h>
#include<ctype.h>
#include<fstream>
using namespace std;

ifstream f("struti.in");
ofstream g("struti.out");

#define MaxN 1010
#define MaxDeque 1000100
#define MaxS 10*MaxDeque

int N,M,P,Sol,Nr,Sol2,Nr2;
int A[MaxN][MaxN],BMin[MaxN][MaxN],BMax[MaxN][MaxN],Querry[2][20];
int DequeM[MaxDeque],Dequem[MaxDeque],Pm[MaxDeque],PM[MaxDeque];
char S[MaxS];

void citire(void)
{
	int nr = 0,j=0;
	
	f >> N >> M >> P;
	f.getline(S,10*MaxDeque,EOF);
	for(int i=1;i<=N;i++,nr = 0)
		for(;nr < M;j++)
			if(isdigit(S[j]))
			{
				++ nr;
				for(;isdigit(S[j]);A[i][nr] = A[i][nr]*10+S[j++]-'0');
			}
	for(int i=1;i<=P;i++)
	{
		for(;!isdigit(S[j]);j++);
		for(;isdigit(S[j]);Querry[0][i] = Querry[0][i]*10+S[j++]-'0');
		for(;!isdigit(S[j]);j++);
		for(;isdigit(S[j]);Querry[1][i] = Querry[1][i]*10+S[j++]-'0');
	}
}

inline void CreareMatriceMinim(int x)
{
	int Front,Back;
	
	for(int i=1;i<=M;i++)
	{
		Front = 1; Back = 0;
		
		for(int j=1;j<=N;j++)
		{
			for(;Back >= Front && Dequem[Back] >= A[j][i];--Back);
			Dequem[++Back] = A[j][i]; Pm[Back] = j;
			
			if(j-Pm[Front] >= x)
				++ Front;
			
			if(j >= x)
				BMin[j][i] = Dequem[Front];
		}
	}
}

inline void CreareMatriceMaxim(int x)
{
	int Front,Back;
	
	for(int i=1;i<=M;i++)
	{
		Front = 1; Back = 0;
		
		for(int j=1;j<=N;j++)
		{
			for(;Back >= Front && DequeM[Back] <= A[j][i];--Back);
			DequeM[++Back] = A[j][i]; PM[Back] = j;
			
			if(j-PM[Front] >= x)
				++ Front;
			
			if(j >= x)
				BMax[j][i] = DequeM[Front];
		}
	}
}

inline void Dinamica(int x,int y)
{
	int FrontMin,BackMin,FrontMax,BackMax;
	
	CreareMatriceMinim(x);
	CreareMatriceMaxim(x);
	
	Sol2 = MaxDeque;
	
	for(int i=x;i<=N;i++)
	{
		FrontMin = FrontMax = 1; BackMin = BackMax = 0;
		
		for(int j=1;j<=M;j++)
		{
			for(;BackMin >= FrontMin && Dequem[BackMin] >= BMin[i][j];--BackMin);
			Dequem[++BackMin] = BMin[i][j]; Pm[BackMin] = j;
			
			if(j-Pm[FrontMin] >= y)
				++ FrontMin;
			
			for(;BackMax >= FrontMax && DequeM[BackMax] <= BMax[i][j];--BackMax);
			DequeM[++BackMax] = BMax[i][j]; PM[BackMax] = j;
			
			if(j-PM[FrontMax] >= y)
				++ FrontMax;
			
			if(j >= y)
				if(Sol2 > DequeM[FrontMax]-Dequem[FrontMin])
					Sol2 = DequeM[FrontMax]-Dequem[FrontMin], Nr2 = 1;
				else if(Sol2 == DequeM[FrontMax]-Dequem[FrontMin])
					Nr2 ++;
		}
	}
}

void Rezolvare(void)
{
	int a,b;
	
	for(int i=1;i<=P;i++)
	{
		a = Querry[0][i];
		b = Querry[1][i];
		Dinamica(a,b);
		Sol = Sol2; Nr = Nr2;
		if(a != b)
		{
			Dinamica(b,a);
			if(Sol > Sol2)
				Sol = Sol2, Nr = Nr2;
			else if(Sol == Sol2)
				Nr += Nr2;
		}
		
		g << Sol << " " << Nr << "\n";
	}
}

int main()
{
	citire();
	Rezolvare();
}