Cod sursa(job #775774)

Utilizator tester9x9Tester9x9 tester9x9 Data 8 august 2012 21:00:01
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.86 kb
#include <fstream>
#include <cstdio>
#include <cstring>
#include <deque>
#define INF 0x3f3f3f
#define N 1010

using namespace std;

FILE* fin=fopen("struti.in","r");
FILE* fout=fopen("struti.out","w");
const int maxb=8192;
char buf[maxb];
int ptr=0;

inline int getint() {
    int nr=0;
    while(buf[ptr]<'0'||'9'<buf[ptr])
        if (++ptr>=maxb) fread(buf,maxb,1,fin),ptr=0;
    while ('0'<=buf[ptr]&&buf[ptr]<='9') {
        nr=nr*10+buf[ptr]-'0';
        if (++ptr>=maxb) fread(buf,maxb,1,fin),ptr=0;
    }
    return nr;
}

int n,m,i,j,A[N][N],Min[N][N],Max[N][N],dx,dy,p,ANS,MANS;


void Solve (int dx, int dy)
{
    register int i,j;
    for (i=1;i<=n;i++)
    {
        deque<int> MaxD,MinD;
        for (j=1;j<dy;j++)
        {
           while (!MinD.empty() && A[i][MinD.back()]>=A[i][j]) MinD.pop_back();
           while (!MaxD.empty() && A[i][MaxD.back()]<=A[i][j]) MaxD.pop_back();
           MinD.push_back(j);
           MaxD.push_back(j);
        }
        for (j=dy;j<=m;j++)
        {
            while (!MinD.empty() && MinD.front()<=j-dy) MinD.pop_front();
            while (!MaxD.empty() && MaxD.front()<=j-dy) MaxD.pop_front();
            while (!MinD.empty() && A[i][MinD.back()]>=A[i][j]) MinD.pop_back();
            while (!MaxD.empty() && A[i][MaxD.back()]<=A[i][j]) MaxD.pop_back();
            MinD.push_back(j);
            MaxD.push_back(j);
            Min[i][j]=A[i][MinD.front()];
            Max[i][j]=A[i][MaxD.front()];
        }
    }
    for (j=dy;j<=m;j++)
    {
        deque<int> MaxD,MinD;
        for (i=1;i<dx;i++)
        {
            while (!MinD.empty() && Min[MinD.back()][j]>=Min[i][j]) MinD.pop_back();
            while (!MaxD.empty() && Max[MaxD.back()][j]<=Max[i][j]) MaxD.pop_back();
            MinD.push_back(i);
            MaxD.push_back(i);
        }
        for (i=dx;i<=n;i++)
        {
            while (!MinD.empty() && MinD.front()<=i-dx) MinD.pop_front();
            while (!MaxD.empty() && MaxD.front()<=i-dx) MaxD.pop_front();
            while (!MinD.empty() && Min[MinD.back()][j]>=Min[i][j]) MinD.pop_back();
            while (!MaxD.empty() && Max[MaxD.back()][j]<=Max[i][j]) MaxD.pop_back();
            MinD.push_back(i);
            MaxD.push_back(i);
            int CANS=Max[MaxD.front()][j]-Min[MinD.front()][j];
            if (CANS<ANS)
            {
                ANS=CANS;
                MANS=0;
            }
            if (CANS==ANS) MANS++;
        }
    }
}


int main ()
{
    n=getint();m=getint();p=getint();
    for (i=1;i<=n;i++)
        for (j=1;j<=m;j++)
            A[i][j]=getint();
    for (i=1;i<=p;i++)
    {
        dx=getint();dy=getint();
        ANS=INF;MANS=0;
        Solve(dx,dy);
        if (dx!=dy) Solve(dy,dx);
        fprintf(fout,"%d %d\n",ANS,MANS);
    }
    fclose(fin);fclose(fout);
    return 0;
}