Cod sursa(job #1651840)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 13 martie 2016 23:02:30
Problema Struti Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.66 kb
#include <fstream>
#include <iostream>
#include <functional>
#include <vector>
#include <deque>
#include <utility>
#include <array>
using namespace std;

template <int sz>
class pstream{
	ifstream f;
	array<char, sz> buf;
	int poz;
	void adv(){
		++poz;
		if(poz == sz){
			poz = 0;
			f.read(&buf[0], sz); } }
public:
	pstream(const char * const name): f(name), poz(sz-1){
		adv(); }
	pstream& operator>>(int& x){
		for( ; !isdigit(buf[poz]); adv());
		for(x = 0; isdigit(buf[poz]); adv()){
			x = 10 * x + buf[poz] - '0'; }
		return *this; } };

template <typename In, typename Out, typename Cmp>
void do_deque(const int n, const int l, In v, Out rez, Cmp cmp){
	deque<int> dq;
	auto push_dq = [&dq, &cmp](const int t){
		while(!dq.empty() && cmp(t, dq.back())){
			dq.pop_back(); }
		dq.push_back(t); };

	auto pop_dq = [&dq](const int t){
		if(!dq.empty() && dq.front() == t){
			dq.pop_front(); } };

	for(int i = 0; i < l; ++i){
		push_dq(v(i)); }

	rez(0) = dq.front();
	for(int i = l; i < n; ++i){
		push_dq(v(i));
		pop_dq(v(i-l));
		rez(i-l+1) = dq.front(); } }

template <typename Cmp>
void do_2d_deque(const int dl, const int dc, const vector<vector<int>>& v, vector<vector<int>>& rez, Cmp cmp){
	const int n = v.size(), m = v[0].size();
	vector<vector<int>> tmp(n, vector<int>(m));
	for(int i = 0; i < n; ++i){
		do_deque(m, dc, [&v, i](const int x){ return v[i][x]; },
			[&tmp, i](const int x)->int&{ return tmp[i][x]; },
			cmp); }
	for(int i = 0; i < m; ++i){
		do_deque(n, dl, [&tmp, i](const int x){ return tmp[x][i]; },
			[&rez, i](const int x)->int&{ return rez[x][i]; },
			cmp); } }

void best_for_dl_dc(const vector<vector<int>>& v, const int dl, const int dc, int& best, int& cnt){
	const int n = v.size(), m = v[0].size();
	vector<vector<int>> mins(n, vector<int>(m)), maxs(n, vector<int>(m));
	do_2d_deque(dl, dc, v, mins, less<int>());
	do_2d_deque(dl, dc, v, maxs, greater<int>());

	for(int i = 0; i+dl <= n; ++i){
		for(int j = 0; j+dc <= m; ++j){
			const int delta = maxs[i][j] - mins[i][j];
			if(delta < best){
				best = delta;
				cnt = 1; }
			else if(delta == best){
				++cnt; } } } }
	
void find_ans_for_q(const vector<vector<int>>& v, const int dl, const int dc, int& best, int& cnt){
	best = 1000000, cnt = 0;
	best_for_dl_dc(v, dl, dc, best, cnt);
	best_for_dl_dc(v, dc, dl, best, cnt); }

int main(){
	pstream<1000> f("struti.in");
	ofstream g("struti.out");
	int n, m, p;
	f >> n >> m >> p;

	vector<vector<int>> v(n, vector<int>(m));
	for(auto& x : v){
		for(auto& y : x){
			f >> y; } }

	for(int i = 0, dl, dc, best, cnt; i < p; ++i){
		f >> dl >> dc;
		find_ans_for_q(v, dl, dc, best, cnt);
		if(dl == dc){
			cnt /= 2; }
		g << best << ' ' << cnt << '\n'; }


	return 0; }