Cod sursa(job #63550)

Utilizator devilkindSavin Tiberiu devilkind Data 29 mai 2007 14:12:22
Problema Struti Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.56 kb
#include <stdio.h>
#define NMAX 1005

long int dx,dy,n,i,j,k,a[NMAX][NMAX],b[NMAX][NMAX],m,p;
long int max[NMAX][NMAX],min[NMAX][NMAX];
long int D[NMAX][2];

void citire()
{
freopen("struti.in","r",stdin);
freopen("struti.out","w",stdout);
scanf("%ld %ld %ld",&n,&m,&p);
for (i=1;i<=n;i++)
        for (j=1;j<=m;j++)
                scanf("%ld",&a[i][j]);
}

void rotire()
{
for (i=1;i<=m;i++)
        for (j=1;j<=n;j++)
                b[i][j]=a[j][m-i+1];
}


void procminim(long int dy)
{
long int st,dr,x;
for (i=1;i<=m;i++)
        {
        st=1;
        dr=0;
        for (j=1;j<=dy;j++)
               {
               while ((D[dr][0]>b[i][j])&&(dr>=st))
                                dr--;
               D[++dr][0]=b[i][j];
               D[dr][1]=j;
               }
        min[1][m-i+1]=D[st][0];
        for (j=2;j<=n-dy+1;j++)
             {
             x=b[i][j+dy-1];
             while ((D[dr][0]>x)&&(dr>=st))
                        dr--;
             D[++dr][0]=x;
             D[dr][1]=j+dy-1;
             while (D[st][1]<j) st++;             
             min[j][m-i+1]=D[st][0];
             }
        }
}

void procmaxim(long int dy)
{
long int st,dr,x;
for (i=1;i<=m;i++)
        {
        st=1;
        dr=0;
        for (j=1;j<=dy;j++)
               {
               while ((D[dr][0]<b[i][j])&&(dr>=st))
                                dr--;
               D[++dr][0]=b[i][j];
               D[dr][1]=j;
               }
        max[1][m-i+1]=D[st][0];
        for (j=2;j<=n-dy+1;j++)
             {
             x=b[i][j+dy-1];
             while ((D[dr][0]<x)&&(dr>=st))
                        dr--;
             D[++dr][0]=x;
             D[dr][1]=j+dy-1;
             while (D[st][1]<j) st++;
             max[j][m-i+1]=D[st][0];
             }
        }
}
long int rez,nr;
long int DMAX[NMAX][2],DMIN[NMAX][2],x;

void query(long int dx, long int dy)
{
long int minim,maxim,st1,st2,dr1,dr2;
procminim(dy);
procmaxim(dy);
for (i=1;i<=n-dy+1;i++)
        {
        st1=1;dr1=0;st2=1;dr2=0;
        for (j=1;j<=dx;j++)
                {
                while ((min[i][j]<DMIN[dr1][0])&&(dr1>=st1)) dr1--;
                DMIN[++dr1][0]=min[i][j];
                DMIN[dr1][1]=j;
                
                while ((max[i][j]>DMAX[dr2][0])&&(dr2>=st2)) dr2--;
                DMAX[++dr2][0]=max[i][j];
                DMAX[dr2][1]=j;
                }
        maxim=DMAX[st2][0];minim=DMIN[st1][0];
        if (maxim-minim<rez) {rez=maxim-minim;nr=1;}
                    else if (maxim-minim==rez) nr++;
        for (j=2;j<=m-dx+1;j++)
                {
                x=min[i][j+dx-1];
                while ((x<DMIN[dr1][0])&&(dr1>=st1)) dr1--;
                DMIN[++dr1][0]=x;
                DMIN[dr1][1]=j+dx-1;

                x=max[i][j+dx-1];
                while ((x>DMAX[dr2][0])&&(dr2>=st2)) dr2--;
                DMAX[++dr2][0]=x;
                DMAX[dr2][1]=j+dx-1;

                while (DMIN[st1][1]<j) st1++;
                while (DMAX[st2][1]<j) st2++;
                
                minim=DMIN[st1][0];maxim=DMAX[st2][0];
                if (maxim-minim<rez) {rez=maxim-minim;nr=1;}
                        else if (maxim-minim==rez) nr++;
                }
        }
}

int main()
{
citire();
rotire();
long int x;
long int i;
for (i=1;i<=p;i++)
        {scanf("%ld %ld",&dx,&dy);
        rez=5000;nr=0;
        query(dx,dy);
        if (dx!=dy)
                query(dy,dx);
        printf("%ld %ld\n",rez,nr);
        }
return 0;
}