Cod sursa(job #616897)

Utilizator dushmiMihai-Alexandru Dusmanu dushmi Data 13 octombrie 2011 16:54:12
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.04 kb
// test savim
#include <cstdio>
#define maxl 1010

int n,m,i,j,k,l,c,nr,p,q;
int a[maxl][maxl],b_min[maxl][maxl],b_max[maxl][maxl];
int numar[8010];

int deque(int l, int c)
{
    int i,j,stm,drm,stM,drM,min=10000,nr;
    int deque_min[maxl],deque_max[maxl];
    
    for (i=1; i<=n; i++)
        for (j=1; j<=m; j++)
        {
            b_min[i][j]=0;
            b_max[i][j]=0;
        }    
    
    //fac matricea cu deque
    for (j=1; j<=m; j++)
    {
        stm=1;drm=0;stM=1;drM=0;
        for (i=1; i<=l; i++)
        {
            deque_min[++drm]=i;
            while (drm-1>0 && a[deque_min[drm]][j]<a[deque_min[drm-1]][j])
            {
                  deque_min[drm-1]=deque_min[drm];
                  deque_min[drm--]=0;
            }
            
            deque_max[++drM]=i;
            while (drM-1>0 && a[deque_max[drM]][j]>a[deque_max[drM-1]][j])
            {
                  deque_max[drM-1]=deque_max[drM];
                  deque_max[drM--]=0;
            }
        }
        b_min[l][j]=a[deque_min[1]][j];b_max[l][j]=a[deque_max[1]][j];
        
        for (i=l+1; i<=n; i++)
        {
            if (deque_min[stm]<=i-l) stm++;
            deque_min[++drm]=i;
            while (drm-1>0 && a[deque_min[drm]][j]<a[deque_min[drm-1]][j])
            {
                  deque_min[drm-1]=deque_min[drm];
                  deque_min[drm--]=0;
            }
            if (drm<stm) stm=drm;
            
            if (deque_max[stM]<=i-l) stM++;
            deque_max[++drM]=i;
            while (drM-1>0 && a[deque_max[drM]][j]>a[deque_max[drM-1]][j])
            {
                  deque_max[drM-1]=deque_max[drM];
                  deque_max[drM--]=0;
            }
            if (drM<stM) stM=drM;
            
            b_min[i][j]=a[deque_min[stm]][j];
            b_max[i][j]=a[deque_max[stM]][j];
        }
    }
    
    /*aflu distanta minimca folosind b_min[i][j] = elementul minim in intervalul [i][j],[i-l+1][j]
      si b_max[i][j] = elementul maxim in intervalul [i][j],[i-l+1][j] */
    for (i=l; i<=n; i++)
    {
        stm=1;drm=0;stM=1;drM=0;
        for (j=1; j<=c; j++)
        {
            deque_min[++drm]=j;
            while (drm-1>0 && b_min[i][deque_min[drm]]<b_min[i][deque_min[drm-1]])
            {
                  deque_min[drm-1]=deque_min[drm];
                  deque_min[drm--]=0;
            }
            
            deque_max[++drM]=j;
            while (drM-1>0 && b_max[i][deque_max[drM]]>b_max[i][deque_max[drM-1]])
            {
                  deque_max[drM-1]=deque_max[drM];
                  deque_max[drM--]=0;
            }
        }
    
        nr=b_max[i][deque_max[1]]-b_min[i][deque_min[1]];
        if (nr<min)
           min=nr;
        numar[nr]++;
        
        for (j=c+1; j<=m; j++)
        {
            if (deque_min[stm]<=j-c) stm++;
            deque_min[++drm]=j;
            while (drm-1>0 && b_min[i][deque_min[drm]]<b_min[i][deque_min[drm-1]])
            {
                  deque_min[drm-1]=deque_min[drm];
                  deque_min[drm--]=0;
            }
            if (drm<stm) stm=drm;
            
            if (deque_max[stM]<=j-c) stM++;
            deque_max[++drM]=j;
            while (drM-1>0 && b_max[i][deque_max[drM]]>b_max[i][deque_max[drM-1]])
            {
                  deque_max[drM-1]=deque_max[drM];
                  deque_max[drM--]=0;
            }
            if (drM<stM) stM=drM;
            
            nr=b_max[i][deque_max[stM]]-b_min[i][deque_min[stm]];
            if (nr<min)
               min=nr;
            numar[nr]++;
        }   
    }
    
    return min;
}

int main()
{
    freopen("struti.in","r",stdin);
    freopen("struti.out","w",stdout);
    
    scanf("%d %d %d",&n,&m,&k);
    for (i=1; i<=n; i++)
        for (j=1; j<=m; j++)
            scanf("%d",&a[i][j]);
    for (i=1; i<=k; i++)
    {
        scanf("%d %d",&l,&c);
        for (j=0; j<=8000; j++) numar[j]=0;
        
        p=deque(l,c);q=10000;
        if (l!=c) q=deque(c,l);

        if (p<q) nr=p;
        else nr=q;
        
        printf("%d %d\n",nr,numar[nr]);
    }
    
    return 0;    
}