Cod sursa(job #1772085)

Utilizator GinguIonutGinguIonut GinguIonut Data 6 octombrie 2016 14:54:30
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.77 kb
#include <fstream>
#include <limits.h>

#define nMax 1001
#define mMax 1001
#define qMax 11
#define INF INT_MAX

using namespace std;

ifstream fin("struti.in");
ofstream fout("struti.out");

int n, m, q, l, L, Min1, Min2, Sol1, Sol2, Sol, Mint;
int dequeMin[nMax], dequeMax[nMax], Min[nMax][mMax], Max[nMax][mMax], mat[nMax][mMax];

void deque_hor(int l)
{
    for(int i=1; i<=n; i++)
    {
        int stMin=1, drMin=0, stMax=1, drMax=0;

        for(int j=1; j<=m; j++)
        {
            if(j-dequeMin[stMin]>=l && stMin<=drMin)
                stMin++;
            if(j-dequeMax[stMax]>=l && stMax<=drMax)
                stMax++;

            while(drMax>=stMax && mat[i][j]>=mat[i][dequeMax[drMax]])
                drMax--;
            dequeMax[++drMax]=j;

            while(drMin>=stMin && mat[i][j]<=mat[i][dequeMin[drMin]])
                drMin--;
            dequeMin[++drMin]=j;

            if(j>=l)
            {
                Min[i][j]=mat[i][dequeMin[stMin]];
                Max[i][j]=mat[i][dequeMax[stMax]];
            }

        }
    }
}

void deque_vert(int L, int l)
{
    for(int j=L; j<=m; j++)
    {
        int stMin=1, drMin=0, stMax=1, drMax=0;

        for(int i=1; i<=n; i++)
        {
            if(i-dequeMin[stMin]>=l && stMin<=drMin)
                stMin++;
            if(i-dequeMax[stMax]>=l && stMax<=drMax)
                stMax++;

            while(drMax>=stMax && Max[i][j]>=Max[dequeMax[drMax]][j])
                drMax--;
            dequeMax[++drMax]=i;

            while(drMin>=stMin && Min[i][j]<=Min[dequeMin[drMin]][j])
                drMin--;
            dequeMin[++drMin]=i;

            if(i>=l)
            {
                int diff=Max[dequeMax[stMax]][j]-Min[dequeMin[stMin]][j];
                if(diff==Mint)
                    Sol++;
                if(diff<Mint)
                {
                    Mint=diff;
                    Sol=1;
                }
            }
        }
    }
}

void solve(int l, int L)
{
    Min1=INF, Min2=INF, Mint=INF;

    deque_hor(l);
    deque_vert(l, L);
    Min1=Mint, Sol1=Sol;

    if(l!=L)
    {
        Mint=INF, Sol=0;
        deque_hor(L);
        deque_vert(L, l);
        Min2=Mint, Sol2=Sol;
    }

    if(Min1<Min2)
    {
        Mint=Min1;
        Sol=Sol1;
    }

    if(Min2<Min1)
    {
        Mint=Min2;
        Sol=Sol2;
    }

    if(Min1==Min2)
    {
        Mint=Min1;
        Sol=Sol1+Sol2;
    }

    fout<<Mint<<" "<<Sol<<'\n';
}

void read()
{
    fin>>n>>m>>q;

    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            fin>>mat[i][j];

    for(int i=1; i<=q; i++)
    {
        fin>>l>>L;
        solve(l, L);
    }
}

int main()
{
    read();
}