Pagini recente » Cod sursa (job #403609) | Cod sursa (job #561650) | Autentificare | Cod sursa (job #321331) | Cod sursa (job #2021769)
#include <fstream>
#include <vector>
#include <deque>
using namespace std;
ifstream cin("struti.in");
ofstream cout("struti.out");
const int MAX = 1e3 + 17;
deque < int > deq_min;
deque < int > deq_max;
vector < vector < int > > sol_max(MAX, vector < int > (MAX));
vector < vector < int > > sol_min(MAX, vector < int > (MAX));
vector < vector < int > > sol2_min(MAX, vector < int > (MAX));
vector < vector < int > > sol2_max(MAX, vector < int > (MAX));
int count (int sol, int n, int m, int x, int y) {
int cnt = 0;
for (int i = 1; i <= n - y + 1; i ++) {
for (int j = 1; j <= m - x + 1; j ++) {
if (sol2_max[i][j] - sol2_min[i][j] == sol) {
cnt ++;
}
}
}
return cnt;
}
pair < int, int > solve(int x, int y, int n, int m, vector < vector < int > > &mat) {
for (int i = 1; i <= n; i ++) {
deq_min.clear();
deq_max.clear();
for (int j = 1; j <= x; j ++) {
while (deq_min.size() and mat[i][j] <= mat[i][deq_min.back()]) {
deq_min.pop_back();
}
while (deq_max.size() and mat[i][j] >= mat[i][deq_max.back()]) {
deq_max.pop_back();
}
deq_min.push_back(j);
deq_max.push_back(j);
}
sol_min[i][1] = mat[i][deq_min.front()];
sol_max[i][1] = mat[i][deq_max.front()];
for (int j = x + 1; j <= m; j ++) {
if (deq_min.front() <= j - x) {
deq_min.pop_front();
}
if (deq_max.front() <= j - x) {
deq_max.pop_front();
}
while (deq_min.size() and mat[i][j] <= mat[i][deq_min.back()]) {
deq_min.pop_back();
}
while (deq_max.size() and mat[i][j] >= mat[i][deq_max.back()]) {
deq_max.pop_back();
}
deq_min.push_back(j);
deq_max.push_back(j);
sol_min[i][j - x + 1] = mat[i][deq_min.front()];
sol_max[i][j - x + 1] = mat[i][deq_max.front()];
}
}
for (int j = 1; j <= m - x + 1; j ++) {
deq_min.clear();
deq_max.clear();
for (int i = 1; i <= y; i ++) {
while (deq_min.size() and sol_min[i][j] <= sol_min[deq_min.back()][j]) {
deq_min.pop_back();
}
while (deq_max.size() and sol_max[i][j] >= sol_max[deq_max.back()][j]) {
deq_max.pop_back();
}
deq_min.push_back(i);
deq_max.push_back(i);
}
sol2_min[1][j] = sol_min[deq_min.front()][j];
sol2_max[1][j] = sol_max[deq_max.front()][j];
for (int i = y + 1; i <= n; i ++) {
if (deq_min.front() <= i - y) {
deq_min.pop_front();
}
if (deq_max.front() <= i - y) {
deq_max.pop_front();
}
while (deq_min.size() and sol_min[i][j] <= sol_min[deq_min.back()][j]) {
deq_min.pop_back();
}
while (deq_max.size() and sol_max[i][j] >= sol_max[deq_max.back()][j]) {
deq_max.pop_back();
}
deq_min.push_back(i);
deq_max.push_back(i);
sol2_min[i - y + 1][j] = sol_min[deq_min.front()][j];
sol2_max[i - y + 1][j] = sol_max[deq_max.front()][j];
}
}
int sol = 1e5;
for (int i = 1; i <= n - y + 1; i ++) {
for (int j = 1; j <= m - x + 1; j ++) {
if (sol2_max[i][j] - sol2_min[i][j] < sol) {
sol = sol2_max[i][j] - sol2_min[i][j];
}
}
}
int cnt = count(sol, n, m, x, y);
return {sol, cnt};
}
int main() {
int n, m, p;
cin >> n >> m >> p;
vector < vector < int > > mat(n + 1, vector < int > (m + 1));
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= m; j ++) {
cin >> mat[i][j];
}
}
for (int i = 1; i <= p; i ++) {
int x, y;
cin >> x >> y;
pair < int, int > sol1 = solve(x, y, n, m, mat);
if (x == y) {
cout << sol1.first << ' ' << sol1.second << '\n';
continue;
}
pair < int, int > sol2 = solve(y, x, n, m, mat);
if (sol1.first == sol2.first) {
cout << sol1.first << ' ' << sol1.second + sol2.second << '\n';
continue;
}
if (sol1.first > sol2.first) {
swap(sol1, sol2);
}
cout << sol1.first << ' ' << sol1.second << '\n';
}
}