Cod sursa(job #1494926)

Utilizator rocandu16Badulescu Dan Andrei rocandu16 Data 1 octombrie 2015 23:39:22
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.29 kb
#include <stdio.h>
#include <ctype.h>
#include <fstream>

using namespace std;

ifstream f("struti.in");
ofstream g("struti.out");

#define MaxN 1010
#define MaxDeque 1010
#define MaxS 7*MaxN*MaxN

int N,M,P,Sol,Nr,Sol2,Nr2;
short int A[MaxN][MaxN],BMin[MaxN][MaxN],BMax[MaxN][MaxN],Querry[2][20];
int DequeM[MaxDeque],Dequem[MaxDeque],Pm[MaxDeque],PM[MaxDeque];
char S[MaxS];

void citire(void)
{
    int nr = 0,j=0;

    f >> N >> M >> P;
    f.getline(S,MaxS,EOF);
    for(int i=1;i<=N;i++,nr = 0)
        for(;nr < M;j++)
            if(isdigit(S[j]))
            {
                ++ nr;
                for(;isdigit(S[j]);A[i][nr] = A[i][nr]*10+S[j++]-'0');
            }
    for(int i=1;i<=P;i++)
    {
        for(;!isdigit(S[j]);j++);
        for(;isdigit(S[j]);Querry[0][i] = Querry[0][i]*10+S[j++]-'0');
        for(;!isdigit(S[j]);j++);
        for(;isdigit(S[j]);Querry[1][i] = Querry[1][i]*10+S[j++]-'0');
    }
}

inline void CreareMatriceMinim(int x)
{
    int Front,Back;

    for(int i=1;i<=M;i++)
    {
        Front = 1; Back = 0;

        for(int j=1;j<=N;j++)
        {
            for(;Back >= Front && Dequem[Back] >= A[j][i];--Back);
            Dequem[++Back] = A[j][i]; Pm[Back] = j;

            if(j-Pm[Front] >= x)
                ++ Front;

            if(j >= x)
                BMin[j][i] = Dequem[Front];
        }
    }
}

inline void CreareMatriceMaxim(int x)
{
    int Front,Back;

    for(int i=1;i<=M;i++)
    {
        Front = 1; Back = 0;

        for(int j=1;j<=N;j++)
        {
            for(;Back >= Front && DequeM[Back] <= A[j][i];--Back);
            DequeM[++Back] = A[j][i]; PM[Back] = j;

            if(j-PM[Front] >= x)
                ++ Front;

            if(j >= x)
                BMax[j][i] = DequeM[Front];
        }
    }
}

inline void Dinamica(int x,int y)
{
    int FrontMin,BackMin,FrontMax,BackMax;

    CreareMatriceMinim(x);
    CreareMatriceMaxim(x);

    Sol2 = 100000;

    for(int i=x;i<=N;i++)
    {
        FrontMin = FrontMax = 1; BackMin = BackMax = 0;

        for(int j=1;j<=M;j++)
        {
            for(;BackMin >= FrontMin && Dequem[BackMin] >= BMin[i][j];--BackMin);
            Dequem[++BackMin] = BMin[i][j]; Pm[BackMin] = j;

            if(j-Pm[FrontMin] >= y)
                ++ FrontMin;

            for(;BackMax >= FrontMax && DequeM[BackMax] <= BMax[i][j];--BackMax);
            DequeM[++BackMax] = BMax[i][j]; PM[BackMax] = j;

            if(j-PM[FrontMax] >= y)
                ++ FrontMax;

            if(j >= y)
                if(Sol2 > DequeM[FrontMax]-Dequem[FrontMin])
                    Sol2 = DequeM[FrontMax]-Dequem[FrontMin], Nr2 = 1;
                else if(Sol2 == DequeM[FrontMax]-Dequem[FrontMin])
                    Nr2 ++;
        }
    }
}

void Rezolvare(void)
{
    int a,b;

    for(int i=1;i<=P;i++)
    {
        a = Querry[0][i];
        b = Querry[1][i];
        Dinamica(a,b);
        Sol = Sol2; Nr = Nr2;
        if(a != b)
        {
            Dinamica(b,a);
            if(Sol > Sol2)
                Sol = Sol2, Nr = Nr2;
            else if(Sol == Sol2)
                Nr += Nr2;
        }

        g << Sol << " " << Nr << "\n";
    }
}

int main()
{
    citire();
    Rezolvare();
}