Cod sursa(job #634318)

Utilizator cont_de_testeCont Teste cont_de_teste Data 15 noiembrie 2011 22:11:16
Problema Struti Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.45 kb
# include <cstdio>

# define verf ++poz == hg ? fread ( ch, 1, hg, stdin ), poz = 0 : 0

const char *FIN = "struti.in", *FOU = "struti.out";
const int MAX = 1005, oo = 0x3f3f3f3f, hg = 1 << 13;

int mini[MAX], maxi[MAX], A[MAX][MAX], minm[MAX][MAX], maxm[MAX][MAX], MINm[MAX][MAX], MAXm[MAX][MAX];
int N, M, T, stm, stM, drm, drM, poz;
char ch[hg];

inline void cit ( int &x ) {
    if ( ch[0] == '\0' ) fread ( ch, 1, hg, stdin ) ;
    else for ( ; ch[poz] < '0' || ch[poz] > '9' ; verf ) ;
    for ( x = 0 ; ch[poz] >= '0' && ch[poz] <= '9' ; x = x * 10 + ch[poz] - '0', verf ) ;
}

inline void solve (int x, int y, int &MIN, int &NR) {
    for (int i = 1; i <= M; ++i) {
        stm = stM = drm = drM = 1;
        mini[1] = maxi[1] = 1, minm[i][1] = maxm[i][1] = A[i][1];
        for (int j = 2; j <= N; ++j) {
            if (j - mini[stm] + 1 > y) ++stm;
            if (j - maxi[stM] + 1 > y) ++stM;
            for (; stm <= drm && A[i][j] < A[i][mini[drm]]; --drm);
            for (; stM <= drM && A[i][j] > A[i][maxi[drM]]; --drM);
            mini[++drm] = maxi[++drM] = j;
            minm[i][j] = A[i][mini[stm]];
            maxm[i][j] = A[i][maxi[stM]];
        }
    }
    for (int i = 1; i <= N; ++i) {
        stm = stM = drm = drM = 1;
        mini[1] = maxi[1] = 1, MINm[1][i] = minm[1][i], MAXm[1][i] = maxm[1][i];
        for (int j = 2; j <= M; ++j) {
            if (j - mini[stm] + 1 > x) ++stm;
            if (j - maxi[stM] + 1 > x) ++stM;
            for (; stm <= drm && minm[j][i] < minm[mini[drm]][i]; --drm);
            for (; stM <= drM && maxm[j][i] > maxm[maxi[drM]][i]; --drM);
            mini[++drm] = maxi[++drM] = j;
            MINm[j][i] = minm[j][mini[stm]];
            MAXm[j][i] = maxm[j][maxi[stM]];
        }
    }
    for (int i = x; i <= M; ++i)
        for (int j = y; j <= N; ++j)
            if (MAXm[i][j] - MINm[i][j] < MIN)
                MIN = MAXm[i][j] - MINm[i][j], NR = 1;
            else if (MAXm[i][j] - MINm[i][j] == MIN)
                NR += 1;
}

int main (void) {
    freopen (FIN, "r", stdin);
    freopen (FOU, "w", stdout);

    cit (M), cit (N), cit (T);
    for (int i = 1; i <= M; ++i)
        for (int j = 1; j <= N; ++j)
            cit (A[i][j]);
    for (int i = 1, x, y; i <= T; ++i) {
        cit (x), cit (y);
        int MIN = oo, NR = 0;
        solve (x, y, MIN, NR);
        if (x != y) solve (y, x, MIN, NR);
        printf ("%d %d\n", MIN, NR);
    }
}