Cod sursa(job #1053876)

Utilizator ELHoriaHoria Cretescu ELHoria Data 12 decembrie 2013 23:36:35
Problema Struti Scor 30
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 3.5 kb
#include <fstream>
#include <map>
#include <vector>
#include <algorithm>
#include <functional>
#include <limits>

using namespace std;

int main()
{
	ifstream cin("struti.in");
	ofstream cout("struti.out");
	int M, N, P;
	cin >> M >> N >> P;
	vector< vector<short> > height(M, vector<short>(N));
	vector<int> LOG2(1 << 10, 0);
	for (int i = 2; i < (1 << 10); i++) {
		LOG2[i] = LOG2[i >> 1] + 1;
	}

	vector < vector< vector< vector< vector<short> > > > > rmq(2);
	rmq[0] = vector< vector< vector< vector<short> > > >(LOG2[M] + 1, vector< vector< vector<short> > >(LOG2[N] + 1,vector< vector<short> >(M,vector<short>(N,numeric_limits<short>::max()))));
	rmq[1] = vector< vector< vector< vector<short> > > >(LOG2[M] + 1, vector< vector< vector<short> > >(LOG2[N] + 1, vector< vector<short> >(M, vector<short>(N,0))));

	for (int i = 0; i < M; i++) {
		for (int j = 0; j < N; j++) {
			cin >> height[i][j];
			rmq[0][0][0][i][j] = height[i][j];
			rmq[1][0][0][i][j] = height[i][j];
		}
	}

	vector< function< short(short, short) > > f;
	f.push_back([](const short &a, const short &b) { return a < b ? a : b; });
	f.push_back([](const short &a, const short &b) { return a > b ? a : b; });

	for (int p = 0; p < 2; p++) {
		for (int i = 1; (1 << i) <= M; i++) {
			for (int k = 0; k < M - (1 << i) + 1; k++) {
				for (int w = 0; w < N; w++) {
					rmq[p][i][0][k][w] = f[p](
						rmq[p][i - 1][0][k][w],
						rmq[p][i - 1][0][k + (1 << (i - 1))][w]
						);
				}
			}
		}

		for (int j = 1; (1 << j) <= N; j++) {
			for (int k = 0; k < M; k++) {
				for (int w = 0; w < N - (1 << j) + 1; w++) {
					rmq[p][0][j][k][w] = f[p](
						rmq[p][0][j - 1][k][w],
						rmq[p][0][j - 1][k][w + (1 << (j - 1))]
						);
				}
			}
		}
	}
	
	for (int p = 0; p < 2; p++) {
		for (int i = 1; (1 << i) <= M; i++) {
			for (int j = 1; (1 << j) <= N; j++) {
				for (int k = 0; k < M - (1 << i) + 1; k++) {
					for (int w = 0; w < N - (1 << j) + 1; w++) {
						rmq[p][i][j][k][w] =
							f[p](
							f[p](
							rmq[p][i - 1][j - 1][k][w + (1 << (j - 1))],
							rmq[p][i - 1][j - 1][k + (1 << (i - 1))][w]
							),
							f[p](
							rmq[p][i - 1][j - 1][k][w],
							rmq[p][i - 1][j - 1][k + (1 << (i - 1))][w + (1 << (j - 1))]
							)
							);
					}
				}
			}
		}
	}

	auto query = [&](int p, int a, int b, int c, int d) {
		int l1 = LOG2[c - a + 1];
		int l2 = LOG2[d - b + 1];
		return
			f[p](
			f[p](
			rmq[p][l1][l2][a][b],
			rmq[p][l1][l2][c - (1 << l1) + 1][b]
			),
			f[p](
			rmq[p][l1][l2][a][d - (1 << l2) + 1],
			rmq[p][l1][l2][c - (1 << l1) + 1][d - (1 << l2) + 1]
			)
			);
	};

	for (int t = 1; t <= P; t++) {
		int d[2];
		cin >> d[0] >> d[1];
		int zoneCount = 0; 
		int ans = numeric_limits<int> ::max();
		int dmax;
		for (int i = 0; i < M; i++) {
			for (int j = 0; j < N; j++) {
				if (i >= d[0] - 1 && j >= d[1] - 1) {
					dmax = query(1, i - d[0] + 1, j - d[1] + 1, i, j) - query(0, i - d[0] + 1, j - d[1] + 1, i, j);
					if (dmax < ans) {
						ans = dmax;
						zoneCount = 1;
					}
					else
					if (dmax == ans) {
						zoneCount++;
					}
				}

				if (d[0] != d[1] && i >= d[1] - 1 && j >= d[0] - 1) {
					dmax = query(1, i - d[1] + 1, j - d[0] + 1, i, j) - query(0, i - d[1] + 1, j - d[0] + 1, i, j);
					if (dmax < ans) {
						ans = dmax;
						zoneCount = 1;
					}
					else
					if (dmax == ans) {
						zoneCount++;
					}
				}
			}
		}

		cout << ans << " " << zoneCount << "\n";
	}

	return 0;
}