Cod sursa(job #1967774)

Utilizator PlayLikeNeverB4George Marcus PlayLikeNeverB4 Data 17 aprilie 2017 01:06:47
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.56 kb
#include <bits/stdc++.h>

using namespace std;

class InParser {
private:
    FILE *fin;
    char *buff;
    int sp;
 
    char read_ch() {
        ++sp;
        if (sp == 4096) {
            sp = 0;
            fread(buff, 1, 4096, fin);
        }
        return buff[sp];
    }
 
public:
    InParser(const char* nume) {
        fin = fopen(nume, "r");
        buff = new char[4096]();
        sp = 4095;
    }
     
    InParser& operator >> (int &n) {
        char c;
        while (!isdigit(c = read_ch()) && c != '-');
        int sgn = 1;
        if (c == '-') {
            n = 0;
            sgn = -1;
        } else {
            n = c - '0';
        }
        while (isdigit(c = read_ch())) {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }
     
    InParser& operator >> (long long &n) {
        char c;
        n = 0;
        while (!isdigit(c = read_ch()) && c != '-');
        long long sgn = 1;
        if (c == '-') {
            n = 0;
            sgn = -1;
        } else {
            n = c - '0';
        }
        while (isdigit(c = read_ch())) {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }
};

#define INF 1000000000
#define MAXN 1050

int N, M, P;
int A[MAXN][MAXN];
int D[MAXN], front, back;
int vmin[MAXN][MAXN], vmax[MAXN][MAXN];
int vmin2D[MAXN][MAXN];

pair<int, int> solve(int dx, int dy) {
  for (int i = 0; i < N; i++) {
    front = 1;
    back = 0;
    for (int j = 0; j < M; j++) {
      while (front <= back && A[i][j] <= A[i][ D[back] ]) {
        back--;
      }
      D[++back] = j;
      if (D[front] == j - dy) {
        front++;
      }
      vmin[i][j] = A[i][ D[front] ];
    }
  }

  for (int j = 0; j < M; j++) {
    front = 1;
    back = 0;
    for (int i = 0; i < N; i++) {
      while (front <= back && vmin[i][j] <= vmin[ D[back] ][j]) {
        back--;
      }
      D[++back] = i;
      if (D[front] == i - dx) {
        front++;
      }
      vmin2D[i][j] = vmin[ D[front] ][j];
    }
  }

  for (int i = 0; i < N; i++) {
    front = 1;
    back = 0;
    for (int j = 0; j < M; j++) {
      while (front <= back && A[i][j] >= A[i][ D[back] ]) {
        back--;
      }
      D[++back] = j;
      if (D[front] == j - dy) {
        front++;
      }
      vmax[i][j] = A[i][ D[front] ];
    }
  }

  int dmin = INF;
  int cnt = 0;
  for (int j = 0; j < M; j++) {
    front = 1;
    back = 0;
    for (int i = 0; i < N; i++) {
      while (front <= back && vmax[i][j] >= vmax[ D[back] ][j]) {
        back--;
      }
      D[++back] = i;
      if (D[front] == i - dx) {
        front++;
      }
      int vmax2D = vmax[ D[front] ][j];

      if (i >= dx - 1 && j >= dy - 1) {
        int diff = vmax2D - vmin2D[i][j];
        if (diff < dmin) {
          dmin = diff;
          cnt = 1;
        } else if (diff == dmin) {
          cnt++;
        }
      }
    }
  }

  return { dmin, cnt };
}

int main() {
	// assert(freopen("struti.in", "r", stdin));
  InParser fin("struti.in");
	assert(freopen("struti.out", "w", stdout));
	cin.sync_with_stdio(false);

	// cin >> N >> M >> P;
  fin >> N >> M >> P;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < M; j++) {
      // cin >> A[i][j];
      fin >> A[i][j];
    }
  }

  int dx, dy;
  while (P-- > 0) {
    // cin >> dx >> dy;
    fin >> dx >> dy;

    auto res = solve(dx, dy);
    if (dx != dy) {
      auto res2 = solve(dy, dx);
      if (res2.first < res.first) {
        res = res2;
      } else if (res2.first == res.first) {
        res.second += res2.second;
      }
    }

    cout << res.first << ' ' << res.second << '\n';
  }

	return 0;
}