Cod sursa(job #1802873)

Utilizator MiricaMateiMirica Matei MiricaMatei Data 10 noiembrie 2016 18:47:48
Problema Struti Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.56 kb
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int a[1005][1005], aux[1005][1005], maxim[1005][1005], minim[1005][1005];
deque<int>d;
void reset_aux(){
  memset(aux, 0, sizeof(aux));
}
void reset_maxim(){
  memset(maxim, 0, sizeof(maxim));
}
void reset_minim(){
  memset(minim, 0, sizeof(minim));
}
void max1(int dx, int  dy, int n, int m){
  int i, j;
  for (i = 1; i <= n; i ++){
    for (j = 1; j <= dx; j ++){
      while (!d.empty() && a[i][j] > a[i][d.back()])
        d.pop_back();
      d.push_back(j);
    }
    aux[i][1] = a[i][d.front()];
    for (j = dx + 1; j <= m; j ++){
      while (!d.empty() && a[i][j] > a[i][d.back()])
        d.pop_back();
      d.push_back(j);
      if (d.front() == j - dx)
        d.pop_front();
      aux[i][j - dx + 1] = a[i][d.front()];
    }
    d.clear();
  }
  for (j = 1; j <= m - dx + 1; j ++){
    for (i = 1; i <= dy; i ++){
      while (!d.empty() && aux[i][j] > aux[d.back()][j])
        d.pop_back();
      d.push_back(i);
    }
    maxim[1][j] = aux[d.front()][j];
    for (i = dy + 1; i <= m; i ++){
      while (!d.empty() && aux[i][j] > aux[d.back()][j])
        d.pop_back();
      d.push_back(i);
      if (d.front() == i - dy)
        d.pop_front();
      maxim[i - dy + 1][j] = aux[d.front()][j];
    }
    d.clear();
  }
}
void min1(int dx, int  dy, int n, int m){
  int i, j;
  for (i = 1; i <= n; i ++){
    for (j = 1; j <= dx; j ++){
      while (!d.empty() && a[i][j] < a[i][d.back()])
        d.pop_back();
      d.push_back(j);
    }
    aux[i][1] = a[i][d.front()];
    for (j = dx + 1; j <= m; j ++){
      while (!d.empty() && a[i][j] < a[i][d.back()])
        d.pop_back();
      d.push_back(j);
      if (d.front() == j - dx)
        d.pop_front();
      aux[i][j - dx + 1] = a[i][d.front()];
    }
    d.clear();
  }
  for (j = 1; j <= m - dx + 1; j ++){
    for (i = 1; i <= dy; i ++){
      while (!d.empty() && aux[i][j] < aux[d.back()][j])
        d.pop_back();
      d.push_back(i);
    }
    minim[1][j] = aux[d.front()][j];
    for (i = dy + 1; i <= m; i ++){
      while (!d.empty() && aux[i][j] < aux[d.back()][j])
        d.pop_back();
      d.push_back(i);
      if (d.front() == i - dy)
        d.pop_front();
      minim[i - dy + 1][j] = aux[d.front()][j];
    }
    d.clear();
  }
}
int main(){
  freopen("struti.in", "r", stdin);
  freopen("struti.out", "w", stdout);
  int n, m, dx, dy, p, ans, ap, i, j, k;
  scanf("%d%d%d", &n, &m, &p);
  for (i = 1; i <= n; i ++)
    for (j = 1; j <= m; j ++)
      scanf("%d", &a[i][j]);
  for (k = 1; k <= p; k ++){
    scanf("%d%d", &dx, &dy);
    ans = (1LL << 31) - 1;
    ap = 0;
    max1(dx, dy, n, m);
    reset_aux();
    min1(dx, dy, n, m);
    reset_aux();
    for (i = 1; i <= n - dy + 1; i ++)
      for (j = 1; j <= m - dx + 1; j ++)
        if (ans > maxim[i][j] - minim[i][j]){
          ans = maxim[i][j] - minim[i][j];
          ap = 1;
        }
        else if (ans == maxim[i][j] - minim[i][j])
          ap ++;
    reset_maxim();
    reset_minim();
    if (dx != dy){
      max1(dy, dx, n, m);
      reset_aux();
      min1(dy, dx, n, m);
      reset_aux();
      for (i = 1; i <= n - dx + 1; i ++)
        for (j = 1; j <= m - dy + 1; j ++)
          if (ans > maxim[i][j] - minim[i][j]){
            ans = maxim[i][j] - minim[i][j];
            ap = 1;
        }
        else if (ans == maxim[i][j] - minim[i][j])
          ap ++;
      reset_maxim();
      reset_minim();
    }
      printf("%d %d\n", ans, ap);
  }
  return 0;
}