Cod sursa(job #2002870)

Utilizator TincaMateiTinca Matei TincaMatei Data 21 iulie 2017 00:59:30
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
#include <cstdio>

const int MAX_N = 1000;
int matr[MAX_N][MAX_N];
int q1[MAX_N], q2[MAX_N], st1, dr1, st2, dr2;

int matrmin[MAX_N][MAX_N], matrmax[MAX_N][MAX_N];

int best, cnt;

inline void solvequery(int n, int m, int dx, int dy) {
  for(int l = 0; l < n; ++l) {
    st1 = dr1 = st2 = dr2 = 0;
    for(int c = 0; c < m; ++c) {
      while(dr1 > st1 && matr[l][c] > matr[l][q1[dr1 - 1]])
        --dr1;
      while(dr2 > st2 && matr[l][c] < matr[l][q2[dr2 - 1]])
        --dr2;
      q1[dr1++] = c;
      q2[dr2++] = c;
      if(c >= dx - 1) {
        matrmax[l][c] = matr[l][q1[st1]];
        matrmin[l][c] = matr[l][q2[st2]];

        if(q1[st1] == c - dx + 1)
          ++st1;
        if(q2[st2] == c - dx + 1)
          ++st2;
      }
    }
  }

  for(int c = dx - 1; c < m; ++c) {
    st1 = dr1 = st2 = dr2 = 0;
    for(int l = 0; l < n; ++l) {
      while(dr1 > st1 && matrmax[l][c] > matrmax[q1[dr1 - 1]][c])
        --dr1;
      while(dr2 > st2 && matrmin[l][c] < matrmin[q2[dr2 - 1]][c])
        --dr2;
      q1[dr1++] = l;
      q2[dr2++] = l;
      if(l >= dy - 1) {
        int delta = matrmax[q1[st1]][c] - matrmin[q2[st2]][c];
        if(delta < best) {
          best = delta;
          cnt = 1;
        } else if(delta == best)
          ++cnt;

        if(q1[st1] == l - dy + 1)
          ++st1;
        if(q2[st2] == l - dy + 1)
          ++st2;
      }
    }
  }
}

int main() {
  int n, m, q, dx, dy;
  FILE *fin = fopen("struti.in", "r");
  FILE *fout = fopen("struti.out", "w");
  fscanf(fin, "%d%d%d", &n, &m, &q);
  for(int l = 0; l < n; ++l)
    for(int c = 0; c < m; ++c)
      fscanf(fin, "%d", &matr[l][c]);
  for(int i = 0; i < q; ++i) {
    fscanf(fin, "%d%d", &dx, &dy);
    best = 1000000;
    cnt = 0;
    solvequery(n, m, dx, dy);
    if(dx != dy)
      solvequery(n, m, dy, dx);
    fprintf(fout, "%d %d\n", best, cnt);
  }
  fclose(fin);
  fclose(fout);
  return 0;
}