Cod sursa(job #1082996)

Utilizator WyvernFMI Stanescu Leonard Wyvern Data 15 ianuarie 2014 14:48:48
Problema Struti Scor 100
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 1.73 kb
#include<cstdio>
#include<cstring>
const int lim=1001;
int n,m,p,x,y,a[lim][lim],min[lim][lim],max[lim][lim];
int stmin,drmin,D[2*lim],V[2*lim],d[2*lim],v[2*lim],drmax,stmax,_min,nr,i,j,aux;
inline void empty(){stmin=1;drmin=0;stmax=1;drmax=0;}
inline int getmin(int k){while(d[stmin]<k) stmin++;return v[stmin];}
inline void addmin(int k,int val){while(drmin>=stmin && v[drmin]>=val) drmin--;d[++drmin]=k;v[drmin]=val;}
inline int getmax(int k){while(D[stmax]<k) stmax++;return V[stmax];}
inline void addmax(int k,int val){while(drmax>=stmax && V[drmax]<=val) drmax--;D[++drmax]=k;V[drmax]=val;}
inline void add(int k,int val){addmin(k,val);addmax(k,val);}
inline void dif(int x,int y) {
    int i,j,dif;
    for(i=1;i<=n;i++){
        empty();
        for(j=1;j<x;j++)
            add(j,a[i][j]);
        for(j=1;j<=m-x+1;j++){
            add(j+x-1,a[i][j+x-1]);
            min[j][i]=getmin(j);
            max[j][i]=getmax(j);}}
    for(i=1;i<=m-x+1;i++){
        empty();
        for(j=1;j<y;j++){
            addmin(j,min[i][j]);
            addmax(j,max[i][j]);}
        for(j=1;j<=n-y+1;j++){
            addmin(j+y-1,min[i][j+y-1]);
            addmax(j+y-1,max[i][j+y-1]);
            dif=getmax(j)-getmin(j);
            if(dif<_min) _min=dif,nr=1;
            else
                if(dif==_min) nr++;
        }
    }
}
int main() {
    freopen("struti.in","r",stdin);
    freopen("struti.out","w",stdout);
    scanf("%d %d %d",&n,&m,&p);
    for(i=1;i<=n;i++)
        for(j=1;j<=m;j++)
            scanf("%d",&a[i][j]);
    for(;p;p--){
        scanf("%d %d",&x,&y);
        _min=10000;
        dif(x,y);
        if(x!=y) dif(y,x);
        printf("%d %d\n",_min,nr);
    }
    fclose(stdout);
    return 0;
}