Cod sursa(job #1500270)

Utilizator mariakKapros Maria mariak Data 11 octombrie 2015 17:53:25
Problema Struti Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.72 kb
#include <cstdio>
#include <algorithm>
#define Dim 1002
#define INF 2000000002

using namespace std;
int n, m, p, M[Dim][Dim], sol, nr, Max[Dim][Dim], Min[Dim][Dim];
int st, dr, St, Dr, dx, dy, dif;
struct nod
{
    int l;
    int c;
} d[Dim], D[Dim];
void read()
{
    freopen("struti.in", "r", stdin);
    freopen("struti.out", "w", stdout);
    scanf("%d %d %d", &n, &m, &p);
    for(int i = 1; i <= n; ++ i)
        for(int j = 1; j <= m; ++ j)
            scanf("%d", &M[i][j]);
}
void field(int a, int b)
{
    int i, j;
    /// matrice de maxime
    for(j = 1; j <= m; ++ j)
    {
        st = 1;
        dr = 0;
        for(i = 1; i <= n; ++ i)
        {
            while(st <= dr && M[d[dr].l][d[dr].c] <= M[i][j])
                dr --;
            d[++ dr].l = i;
            d[dr].c = j;
            while(st <= dr && i - d[st].l == a)
                st ++;
            if(i >= a)
                Max[i - a + 1][j] = M[d[st].l][d[st].c];
        }
    }
    /// matrice de minime
    for(j = 1; j <= m; ++ j)
    {
        st = 1;
        dr = 0;
        for(i = 1; i <= n; ++ i)
        {
            while(st <= dr && M[d[dr].l][d[dr].c] >= M[i][j])
                dr --;
            d[++ dr].l = i;
            d[dr].c = j;
            while(st <= dr && i - d[st].l == a)
                st ++;
            if(i >= a)
                Min[i - a + 1][j] = M[d[st].l][d[st].c];
        }
    }
    /// dif de alt minima dintr-o submatrice de dim a si b
    for(i = 1; i <= n - a + 1; ++ i)
    {
        st = St = 1;
        dr = Dr = 0;
        for(j = 1; j <= m; ++ j)
        {
            while(St <= Dr && Max[D[Dr].l][D[Dr].c] <= Max[i][j])
                Dr --;
            D[++ Dr].l = i;
            D[Dr].c = j;
            while(st <= dr && Min[d[dr].l][d[dr].c] >= Min[i][j])
                dr --;
            d[++ dr].l = i;
            d[dr].c = j;
            while(st <= dr && j - d[st].c == b)
                st ++;
            while(St <= Dr && j - D[St].c == b)
                St ++;
            if(j >= b)
            {
                dif = Max[D[St].l][D[St].c] - Min[d[st].l][d[st].c];
                if(dif == sol)
                    nr ++;
                if(dif < sol)
                {
                    sol = dif;
                    nr = 1;
                }
            }
        }
    }
}
void write()
{
    printf("%d %d\n", sol, nr);
}
void solve()
{
    for(int i = 1; i <= p; ++ i)
    {
        sol = INF;
        nr = 0;
        scanf("%d %d", &dx, &dy);
        field(dx, dy);
        if (dx != dy)
            field(dy, dx);
        write();
    }
}
int main()
{
    read();
    solve();
    return 0;
}