Cod sursa(job #547837)

Utilizator razyelxrazyelx razyelx Data 6 martie 2011 18:53:26
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.54 kb
#include <fstream>
#include <deque>

using namespace std;

const int N = 1100;

ifstream fin("struti.in");
ofstream fout("struti.out");

int t[N][N], n, m, p, x, y, Max[N][N], Min[N][N], best, nr;

void calcMax(int k){ // calculeaza maximul de pe coloane intr-o matrice Max
	deque<int> maxL;
	int i,j;
	
	for (j=1; j<=n; j++){
		
		maxL.clear();
		
		for (i=1; i<=m; i++){
			
			
			while (!maxL.empty() && t[maxL.back()][j] <= t[i][j]) maxL.pop_back();
			maxL.push_back(i);
			
			while (!maxL.empty() && maxL.front() <= i-k) maxL.pop_front();
			
			if (i >= k )
				Max[i-k+1][j] = t[maxL.front()][j];
			
		}
		
		//for (int h=i-k; h<=m; h++)
		//	Max[h][j] = t[maxL.front()][j];
	}
}

void calcMin(int k){ // calcuelaza minimul de pe coloane intr-o matrice Min
	deque<int> minL;
	int i,j;
	
	for (j=1; j<=n; j++){
		
		minL.clear();
		
		for (i=1; i<=m; i++){
			
			
			while (!minL.empty() && t[minL.back()][j] >= t[i][j]) minL.pop_back();
			minL.push_back(i);
			
			while (!minL.empty() && minL.front() <= i-k) minL.pop_front();
			
			if (i >= k )
				Min[i-k+1][j] = t[minL.front()][j];
			
		}
		
		//for (int h=i-k; h<=m; h++)
		//	Min[h][j] = t[minL.front()][j];
	}
}

void solve(int x, int y){
	
	deque<int> MaxDeq, MinDeq;
		
	calcMin(y);// calcuelaza minimul de pe coloane intr-o matrice Min
	calcMax(y);// calculeaza maximul de pe coloane intr-o matrice Max
	
	for (int i=1; i<=m-y+1; i++){
		
		MaxDeq.clear();
		MinDeq.clear();
		
		for (int j=1; j<=n; j++){
		
			while (!MinDeq.empty() && Min[i][MinDeq.back()] >= Min[i][j]) MinDeq.pop_back();
			MinDeq.push_back(j);
			
			while (!MaxDeq.empty() && Max[i][MaxDeq.back()] <= Max[i][j]) MaxDeq.pop_back();
			MaxDeq.push_back(j);
			
			while (!MinDeq.empty() && MinDeq.front() <= j-x) MinDeq.pop_front();
			while (!MaxDeq.empty() && MaxDeq.front() <= j-x) MaxDeq.pop_front();
			
			if (j >= x){
				if (Max[i][MaxDeq.front()] - Min[i][MinDeq.front()] < best) 
					best = Max[i][MaxDeq.front()] - Min[i][MinDeq.front()], nr = 1;
				else
					if (Max[i][MaxDeq.front()] - Min[i][MinDeq.front()] == best) nr++;
			}
			
		}
	
	}		
}

int main(){
	
	int i,j,k,x,y;
	
	fin>>m>>n>>p;
	
	for (int i=1; i<= m; i++)
		for (int j=1; j<=n; j++)
			fin>>t[i][j];
	
	for (k=1; k<=p; k++){
		
		fin>>x>>y;
		
		if (x!=y){
			best = 9000; nr = 0;
			solve(x,y);
			solve(y,x);
			
			fout<<best<<" "<<nr<<"\n";
			
		} else {
			best = 9000; nr = 0;
			solve(x,y);
			
			fout<<best<<" "<<nr<<"\n";
		}
	}
}