Cod sursa(job #1061398)

Utilizator poptibiPop Tiberiu poptibi Data 19 decembrie 2013 18:30:49
Problema Struti Scor 90
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 2.41 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];
deque<int> Dmin, Dmax;

pair<int, int> Cnt(int X, int Y)
{
    int CrtMin = Inf, CrtCnt = 0;
    for(int j = 1; j <= M; ++ j)
    {
        Dmin.clear();
        Dmax.clear();
        for(int i = 1; i <= N; ++ i)
        {
            while(!Dmin.empty() && A[Dmin.back()][j] > A[i][j]) Dmin.pop_back();
            while(!Dmax.empty() && A[Dmax.back()][j] < A[i][j]) Dmax.pop_back();
            Dmin.push_back(i);
            Dmax.push_back(i);
            while(!Dmin.empty() && Dmin.front() <= i - X) Dmin.pop_front();
            while(!Dmax.empty() && Dmax.front() <= i - X) Dmax.pop_front();
            Min[i][j] = A[Dmin.front()][j];
            Max[i][j] = A[Dmax.front()][j];
        }
    }
    for(int i = X; i <= N; ++ i)
    {
        Dmin.clear();
        Dmax.clear();
        for(int j = 1; j <= M; ++ j)
        {
            while(!Dmin.empty() && Min[i][Dmin.back()] > Min[i][j]) Dmin.pop_back();
            while(!Dmax.empty() && Max[i][Dmax.back()] < Max[i][j]) Dmax.pop_back();
            Dmin.push_back(j);
            Dmax.push_back(j);
            while(!Dmin.empty() && Dmin.front() <= j - Y) Dmin.pop_front();
            while(!Dmax.empty() && Dmax.front() <= j - Y) Dmax.pop_front();
            if(j >= Y)
            {
                int Cost = Max[i][Dmax.front()] - Min[i][Dmin.front()];
                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);
        }
    }
}