Cod sursa(job #1493325)

Utilizator alex_HarryBabalau Alexandru alex_Harry Data 29 septembrie 2015 00:02:43
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.06 kb
#include <fstream>
using namespace std;
ifstream f("struti.in");
ofstream g("struti.out");
int N,M,nb;
int Matrix[1005][1005],P,ans=8005,Max[1005][1005],Min[1005][1005],Begin[2][1005],End[2][1005],MMax[1005],MMin[1005],BeginMin=1,BeginMax=1,EndMax,EndMin;
void Read()
{
    f>>N>>M>>P;
    for(int i=1;i<=N;i++)
        for(int j=1;j<=M;j++)
            f>>Matrix[i][j],Begin[0][i]=Begin[1][i]=1;
}
void Update(int L,int C)
{
    BeginMax=BeginMin=1;
    EndMax=EndMin=0;
    for(int i=1;i<=N;i++)
    {
        while(BeginMax<=EndMax && Matrix[i][Max[i][Begin[0][i]]]>=Matrix[MMax[EndMax]][Max[MMax[EndMax]][Begin[0][MMax[EndMax]]]])
            --EndMax;
        MMax[++EndMax]=i;
        if(MMax[BeginMax]==i-L)
            ++BeginMax;
        while(BeginMin<=EndMin && Matrix[i][Min[i][Begin[1][i]]]<=Matrix[MMin[EndMin]][Min[MMin[EndMin]][Begin[1][MMin[EndMin]]]])
            --EndMin;
        MMin[++EndMin]=i;
        if(MMin[BeginMin]==i-L)
            ++BeginMin;
        if(i<L)
            continue;
        int line1=MMax[BeginMax],line2=MMin[BeginMin];
        if(ans==Matrix[line1][Max[line1][Begin[0][line1]]]-Matrix[line2][Min[line2][Begin[1][line2]]])
            ++nb;
        if(ans>Matrix[line1][Max[line1][Begin[0][line1]]]-Matrix[line2][Min[line2][Begin[1][line2]]])
        {
            ans=Matrix[line1][Max[line1][Begin[0][line1]]]-Matrix[line2][Min[line2][Begin[1][line2]]];
            nb=1;
        }
        ans=min(ans,Matrix[line1][Max[line1][Begin[0][line1]]]-Matrix[line2][Min[line2][Begin[1][line2]]]);
    }
}
void Solve(int L,int C)
{
    for(int i=1;i<=N;i++)
    {
        for(int j=1;j<=C;j++)
        {
            while(Begin[0][i]<=End[0][i] && Matrix[i][j]>=Matrix[i][Max[i][End[0][i]]])
                --End[0][i];
            Max[i][++End[0][i]]=j;
            while(Begin[1][i]<=End[1][i] && Matrix[i][j]<=Matrix[i][Min[i][End[1][i]]])
                --End[1][i];
            Min[i][++End[1][i]]=j;
        }
    }
    Update(L,C);
    for(int j=C+1;j<=M;j++)
    {
        for(int i=1;i<=N;i++)
        {
            while(Begin[0][i]<=End[0][i] && Matrix[i][j]>=Matrix[i][Max[i][End[0][i]]])
                --End[0][i];
            Max[i][++End[0][i]]=j;
            if(Max[i][Begin[0][i]]==j-C)
                ++Begin[0][i];
            while(Begin[1][i]<=End[1][i] && Matrix[i][j]<=Matrix[i][Min[i][End[1][i]]])
                --End[1][i];
            Min[i][++End[1][i]]=j;
            if(Min[i][Begin[1][i]]==j-C)
                ++Begin[1][i];
        }
        Update(L,C);
    }

}
int main()
{
    Read();
    for(int i=1;i<=P;i++)
    {
        int L,C;
        f>>L>>C;
        Solve(L,C);

        for(int i=1;i<=N;i++)
            Begin[0][i]=Begin[1][i]=BeginMax=BeginMin=1,End[0][i]=End[1][i]=EndMin=EndMax=0;
        if(C!=L)
            Solve(C,L);
        g<<ans<<" "<<nb<<"\n";
        ans=nb=0;
        ans=8005;
        for(int i=1;i<=N;i++)
            Begin[0][i]=Begin[1][i]=BeginMax=BeginMin=1,End[0][i]=End[1][i]=EndMin=EndMax=0;
    }
    return 0;
}