Cod sursa(job #1059705)

Utilizator Cosmin1490Balan Radu Cosmin Cosmin1490 Data 16 decembrie 2013 21:36:55
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.15 kb
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <iterator>
#include <random>
#include <assert.h>
using namespace std;


const string file = "struti";

const string infile = file + ".in";
const string outfile = file + ".out";

const int INF = 0x3f3f3f3f;


const int NMAX = 1010;

int A[NMAX][NMAX];
int MAX[NMAX][NMAX];
int MIN[NMAX][NMAX];


inline bool asc(int a, int b)
{
	return a < b;
}

inline bool desc(int a, int b)
{
	return a > b;
}

template <class P>
inline void update(deque<pair<int, int> >& deck, int index, int K, int element, P pred)
{
	while(deck.size() > 0 && pred(deck.back().first, element))
	{
		deck.pop_back();
	}

	if(deck.size() > 0 && deck.front().second <= index - K)
	{
		deck.pop_front();
	}

	deck.push_back(make_pair(element, index));
}


inline void Solve(int dx, int dy, int& mini, int& nr, int N, int M)
{
	
	deque<pair<int, int> > dMax;
	deque<pair<int, int> > dMin;

	for(int i = 0; i < N; i++)
	{
		dMax.clear();
		dMin.clear();
		for(int j = 0; j < M; j++)
		{
			update(dMax, j, dy, A[i][j], asc);
			update(dMin, j, dy, A[i][j], desc);

			if(j >= dy - 1)
			{
				MAX[i][j - dy + 1] = dMax.front().first;
				MIN[i][j - dy + 1] = dMin.front().first;
			}
		}
	}

	mini = INF;
	vector<deque<pair<int, int> > > vdMax;
	vector<deque<pair<int, int> > > vdMin;

	vdMax.resize(M - dy + 1);
	vdMin.resize(M - dy + 1);

	for(int i = 0; i < N; i++)
	{
		for(int j = 0; j < M - dy + 1; j++)
		{
			update(vdMax[j], i, dx, MAX[i][j], asc);
			update(vdMin[j], i, dx, MIN[i][j], desc);


			if(i >= dx - 1)
			{
				MAX[i - dx + 1][j] = vdMax[j].front().first;
				MIN[i - dx + 1][j] = vdMin[j].front().first;

				if(MAX[i - dx + 1][j] - MIN[i - dx + 1][j] < mini)
				{
					mini = MAX[i - dx + 1][j] - MIN[i - dx + 1][j];
					nr = 1;
				}
				else if( MAX[i -dx + 1][j] - MIN[i - dx + 1][j] == mini)
				{
					nr++;
				}
			}
		}
	}

}

int main()
{
#ifdef ONLINE_JUDGE
	ostream &fout = cout;
	istream &fin = cin;
#else
	fstream fout(outfile.c_str(), ios::out);
	fstream fin(infile.c_str(), ios::in);
#endif	


	int N, M, P;
	fin >> N >> M >> P;
	for(int i = 0; i < N; i++)
	{
		for(int j = 0; j < M; j++)
		{
			fin >> A[i][j];
		}
	}

	for(int i = 0; i < P; i++)
	{
		int dx, dy;
		fin >> dx >> dy;

		int mini;
		int nr;

		Solve(dx, dy, mini, nr, N, M);

		if(dx != dy)
		{

			int mini2;
			int nr2;

			Solve(dy, dx, mini2, nr2, N, M);
			if(mini == mini2)
			{
				nr += nr2;
			}
			else if(mini2 < mini)
			{
				mini = mini2;
				nr = nr2;
			}
		}

		fout << mini << " " << nr << "\n";
	}

#ifdef ONLINE_JUDGE
#else

	fin.close();
	fout.close();
#endif
}