Cod sursa(job #1256550)

Utilizator MarcvsHdrMihai Leonte MarcvsHdr Data 6 noiembrie 2014 15:19:02
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.95 kb
#include <iostream>
#include <fstream>
#include <queue>

int n, m, p;
int a[1000][1000], min[1000][1000], max[1000][1000];
std::pair<int, int> deq[2000];
int b, e;

template<bool (*better)(int, int)>
void compstat(int stat[][1000], int dx, int dy) {
  for (int col = 0; col < m; ++col) {
    b = 0; e = -1;
    for (int lin = 0; lin < n; ++lin) {
      while (b <= e && better(a[lin][col], deq[e].first)) e--;
      deq[++e] = std::make_pair(a[lin][col], lin);
      while (b <= e && deq[b].second <= lin - dx) b++;
      stat[lin][col] = deq[b].first;
    }
  }

  for (int lin = 0; lin < n; ++lin) {
    b = 0; e = -1;
    for (int col = 0; col < m; ++col) {
      while (b <= e && better(stat[lin][col], deq[e].first)) e--;
      deq[++e] = std::make_pair(stat[lin][col], col);
      while (b <= e && deq[b].second <= col - dy) b++;
      stat[lin][col] = deq[b].first;
    }
  }
}

void count(int min[][1000], int max[][1000], int dx, int dy, int& sol, int& count) {
  for (int i = dx - 1; i < n; ++i) {
    for (int j = dy - 1; j < m; ++j) {
      if (max[i][j] - min[i][j] < sol) {
        sol = max[i][j] - min[i][j];
        count = 1;
      } else if (max[i][j] - min[i][j] == sol) {
        count++;
      }
    }
  }
}

inline bool lessthan(int a, int b) { return a < b; }
inline bool morethan(int a, int b) { return a > b; }

int main()
{
  std::ifstream in("struti.in");
  std::ofstream out("struti.out");

  in >> n >> m >> p;
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      in >> a[i][j];
    }
  }

  for (int i = 0; i < p; ++i) {
    int dx, dy;
    in >> dx >> dy;
    int sol = 1000000;
    int ct = 0;
    compstat<lessthan>(min, dx, dy);
    compstat<morethan>(max, dx, dy);
    count(min, max, dx, dy, sol, ct);
    if (dx != dy) {
      compstat<lessthan>(min, dy, dx);
      compstat<morethan>(max, dy, dx);
      count(min, max, dy, dx, sol, ct);
    }

    out << sol << " " << ct << std::endl;
  }

  in.close();
  out.close();

  return 0;
}