Cod sursa(job #1061399)

Utilizator poptibiPop Tiberiu poptibi Data 19 decembrie 2013 18:36:42
Problema Struti Scor 100
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 2.53 kb
#include <cstdio>
#include <cstdlib>
#include <deque>
#include <algorithm>
using namespace std;

const int NMAX = 1010, Inf = 0x3f3f3f3f;

int N, M, P, DX, DY, A[NMAX][NMAX], DeqMin[NMAX][NMAX], DeqMax[NMAX][NMAX], Min[NMAX][NMAX], Max[NMAX][NMAX];
int Dmin[NMAX], Dmax[NMAX], FrontMin, FrontMax, BackMin, BackMax;

pair<int, int> Cnt(int X, int Y)
{
    int CrtMin = Inf, CrtCnt = 0;
    for(int j = 1; j <= M; ++ j)
    {
        FrontMin = FrontMax = 1;
        BackMin = BackMax = 0;
        for(int i = 1; i <= N; ++ i)
        {
            while(FrontMin <= BackMin && A[Dmin[BackMin]][j] > A[i][j]) BackMin --;
            while(FrontMax <= BackMax && A[Dmax[BackMax]][j] < A[i][j]) BackMax --;
            Dmin[++ BackMin] = i;
            Dmax[++ BackMax] = i;
            while(FrontMin <= BackMin && Dmin[FrontMin] <= i - X) FrontMin ++;
            while(FrontMax <= BackMax && Dmax[FrontMax] <= i - X) FrontMax ++;
            Min[i][j] = A[Dmin[FrontMin]][j];
            Max[i][j] = A[Dmax[FrontMax]][j];
        }
    }
    for(int i = X; i <= N; ++ i)
    {
        FrontMin = FrontMax = 1;
        BackMin = BackMax = 0;
        for(int j = 1; j <= M; ++ j)
        {
            while(FrontMin <= BackMin && Min[i][Dmin[BackMin]] > Min[i][j]) BackMin --;
            while(FrontMax <= BackMax && Max[i][Dmax[BackMax]] < Max[i][j]) BackMax --;
            Dmin[++ BackMin] = j;
            Dmax[++ BackMax] = j;
            while(FrontMin <= BackMin && Dmin[FrontMin] <= j - Y) FrontMin ++;
            while(FrontMax <= BackMax && Dmax[FrontMax] <= j - Y) FrontMax ++;
            if(j >= Y)
            {
                int Cost = Max[i][Dmax[FrontMax]] - Min[i][Dmin[FrontMin]];
                if(Cost < CrtMin) CrtMin = Cost, CrtCnt = 1;
                else if(Cost == CrtMin) CrtCnt ++;
            }
        }
    }
    return make_pair(CrtMin, CrtCnt);
}

int main()
{
    freopen("struti.in", "r", stdin);
    freopen("struti.out", "w", stdout);

    scanf("%i %i %i", &N, &M, &P);
    for(int i = 1; i <= N; ++ i)
        for(int j = 1; j <= M; ++ j)
            scanf("%i", &A[i][j]);
    for(; P; P --)
    {
        scanf("%i %i", &DX, &DY);
        pair<int, int> Cost = Cnt(DX, DY), ReverseCost = Cnt(DY, DX);
        if(Cost.first == ReverseCost.first && DX != DY) printf("%i %i\n", Cost.first, Cost.second + ReverseCost.second);
        else
        {
            pair<int, int> Ans = min(Cost, ReverseCost);
            printf("%i %i\n", Ans.first, Ans.second);
        }
    }
}