Cod sursa(job #2002871)

Utilizator TincaMateiTinca Matei TincaMatei Data 21 iulie 2017 01:03:10
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.3 kb
#include <cstdio>
#include <ctype.h>

const int MAX_N = 1000;
const int BUFF = 4096;
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;

int curs = BUFF - 1;
char buftea[BUFF];

inline char getch(FILE *fin) {
  ++curs;
  if(curs == BUFF) {
    curs = 0;
    fread(buftea, 1, BUFF, fin);
  }
  return buftea[curs];
}

inline int getnr(FILE *fin) {
  char ch;
  int nr = 0;
  ch = getch(fin);
  while(!isdigit(ch))
    ch = getch(fin);
  while(isdigit(ch)) {
    nr = nr * 10 + ch - '0';
    ch = getch(fin);
  }
  return nr;
}

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");
  n = getnr(fin);
  m = getnr(fin);
  q = getnr(fin);
  for(int l = 0; l < n; ++l)
    for(int c = 0; c < m; ++c)
      matr[l][c] = getnr(fin);
  for(int i = 0; i < q; ++i) {
    dx = getnr(fin);
    dy = getnr(fin);
    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;
}