Cod sursa(job #1760527)

Utilizator giotoPopescu Ioan gioto Data 20 septembrie 2016 21:52:10
Problema Struti Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.85 kb
#include <cstdio>
using namespace std;

int nr,minim,k,x,y,n,m,Max[1002][1002],Min[1002][1002],dq[2002],dq1[2002],a[1002][1002],b1[1002][1002],b2[1002][1002];
void construct_table(short l, short c){
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
                b1[i][j]=0,b2[i][j]=0;
    for(int i=1;i<=n;++i){
        //iau dreptunghiul cu coltul pe linia i si coloana j
        int Back=0,Front=0,Back1=0,Front1=0;
        dq[0]=0;dq1[0]=1;
        for(int t=1;t<=c;++t){
            while(Back>=Front&&a[i][dq[Back]]<=a[i][t])
                --Back;
            dq[++Back]=t;
        }
        for(int t=2;t<=c;++t){
            while(Back1>=Front1&&a[i][dq1[Back1]]>=a[i][t])
                --Back1;
            dq1[++Back1]=t;
        }
        b1[i][c]=a[i][dq[Front]];
        b2[i][c]=a[i][dq1[Front1]];
        for(int j=c+1;j<=m;++j){
            while(Back>=Front&&a[i][dq[Back]]<=a[i][j])
                --Back;
            dq[++Back]=j;
            while(Back1>=Front1&&a[i][dq1[Back1]]>=a[i][j])
                --Back1;
            dq1[++Back1]=j;
            if(j-dq[Front]==c) ++Front;
            if(j-dq1[Front]==c) ++Front1;
            b1[i][j]=a[i][dq[Front]];
            b2[i][j]=a[i][dq1[Front1]];
        }
    }
    for(int j=c;j<=m;++j){
        int Back=0,Front=0,Back1=0,Front1=0;
        dq[Back]=1;dq1[Back]=1;
        Min[1][j]=b2[dq[Front]][j];Max[1][j]=b1[dq[Front]][j];
        for(int i=2;i<=n;++i){
            while(Back>=Front&&b1[dq[Back]][j]<=b1[i][j])
                --Back;
            dq[++Back]=i;
            if(i-dq[Front]==l) ++Front;
            Max[i][j]=b1[dq[Front]][j];
            while(Back1>=Front1&&b2[dq1[Back1]][j]>=b2[i][j])
                --Back1;
            dq1[++Back1]=i;
            if(i-dq1[Front1]==l) ++Front1;
            Min[i][j]=b2[dq1[Front1]][j];
        }
    }
    for(int i=l;i<=n;++i)
        for(int j=c;j<=m;++j){
            if(Max[i][j]-Min[i][j]<minim){nr=1;minim=Max[i][j]-Min[i][j];}
            else if(Max[i][j]-Min[i][j]==minim)++nr;
        }
//    for(int i=1;i<=n;++i){
//        for(int j=1;j<=m;++j){
//            printf("%d ", Max[i][j]);
//        }printf("\n");
//    }printf("\n");
//    for(int i=1;i<=n;++i){
//        for(int j=1;j<=m;++j){
//            printf("%d ", Min[i][j]);
//        }printf("\n");
//    }printf("\n");
}
int main()
{
    freopen("struti.in", "r", stdin);
    freopen("struti.out", "w", stdout);
    scanf("%d%d%d", &n,&m,&k);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            scanf("%d", &a[i][j]);
    for(int t=1;t<=k;++t){
        minim=2000000000;nr=0;
        scanf("%d%d", &x,&y);
        construct_table(x,y);
        if(x==y) {printf("%d %d\n",minim,nr);continue;}
        construct_table(y,x);
        printf("%d %d\n",minim,nr);
    }
    return 0;
}