Cod sursa(job #3366897)

Utilizator BurloiEmilAndreiBurloi Emil Andrei BurloiEmilAndrei Data 5 octombrie 2026 10:46:21
Problema Struti Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.67 kb
#include <bits/stdc++.h>
using namespace std;

/* custom dq structure which allows querying for smallest element according to cmp_func */
template <typename F>
struct custom_dq {
  deque<int> dq;
  F cmp_func;

  /* cmp_func(a, b) gives the (weak) ordering in the deque */
  custom_dq(F& cmp_func) : cmp_func(cmp_func) {}

  void clear() {
    while (!dq.empty()) {
      dq.pop_back();
    }
  }
  void add_element(int x) {
    while (!dq.empty() && !cmp_func(dq.back(), x)) {
      dq.pop_back();
    }
    dq.push_back(x);
  }
  void remove_element(int x) {
    if (dq.front() == x) {
      dq.pop_front();
    }
  }
  int get_best() {
    return dq.front();
  }
};

int main() {
  if (fopen("struti.in", "r")) {
    freopen("struti.in", "r", stdin);
    freopen("struti.out", "w", stdout);
  }
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, m, q;
  cin >> n >> m >> q;
  vector<vector<int>> a(n, vector<int>(m));
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> a[i][j];
    }
  }
  auto compress_rows = [&](int h, int w, const vector<vector<int>>& b, auto cmp_func) {
    int n = b.size(), m = b[0].size();
    vector<vector<int>> compressed_mat(n, vector<int>(m - w + 1));
    custom_dq dq(cmp_func);
    for (int i = 0; i < n; i++) {
      dq.clear();
      for (int j = 0; j < w; j++) {
        dq.add_element(b[i][j]);
      }
      for (int j = w; j < m; j++) {
        compressed_mat[i][j - w] = dq.get_best();
        dq.remove_element(b[i][j - w]);
        dq.add_element(b[i][j]);
      }
      compressed_mat[i][m - w] = dq.get_best();
    }
    return compressed_mat;
  };
  auto compress_cols = [&](int h, int w, const vector<vector<int>>& b, auto cmp_func) {
    int n = b.size(), m = b[0].size();
    vector<vector<int>> compressed_mat(n - h + 1, vector<int>(m));
    custom_dq dq(cmp_func);
    for (int j = 0; j < m; j++) {
      dq.clear();
      for (int i = 0; i < h; i++) {
        dq.add_element(b[i][j]);
      }
      for (int i = h; i < n; i++) {
        compressed_mat[i - h][j] = dq.get_best();
        dq.remove_element(b[i - h][j]);
        dq.add_element(b[i][j]);
      }
      compressed_mat[n - h][j] = dq.get_best();
    }
    return compressed_mat;
  };
  auto compress_matrix = [&](int h, int w, const vector<vector<int>>& b, auto cmp_func) {
    vector<vector<int>> mat = compress_rows(h, w, b, cmp_func);
    return compress_cols(h, w, mat, cmp_func);
  };
  auto compute_answer = [&](int h, int w) {
    vector<vector<int>> compressed_max_mat = compress_matrix(h, w, a, [](int x, int y) {
      return x >= y;
    });
    vector<vector<int>> compressed_min_mat = compress_matrix(h, w, a, [](int x, int y) {
      return x <= y;
    });
    int n = compressed_max_mat.size(), m = compressed_max_mat[0].size();
    int mn = numeric_limits<int>::max(), cnt_mn = 0;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        int delta = compressed_max_mat[i][j] - compressed_min_mat[i][j];
        if (delta < mn) {
          mn = delta;
          cnt_mn = 1;
        } else if (delta == mn) {
          cnt_mn += 1;
        }
      }
    }
    return make_pair(mn, cnt_mn);
  };
  while (q--) {
    int nx, ny;
    cin >> nx >> ny;
    pair<int, int> answer = compute_answer(nx, ny);
    if (nx != ny) {
      pair<int, int> alternative_answer = compute_answer(ny, nx);
      if (alternative_answer.first == answer.first) {
        answer.second += alternative_answer.second;
      } else {
        answer = min(answer, alternative_answer);
      }
    }
    cout << answer.first << ' ' << answer.second << '\n';
  }
  return 0;
}