Cod sursa(job #1179680)

Utilizator timicsIoana Tamas timics Data 29 aprilie 2014 01:02:03
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.94 kb
#include<stdio.h>
#include<deque>
using namespace std;

int N,M,P,A,B,rez,cnt,a[1010][1010],mnh[1010][1010],mxh[1010][1010],mnv[1010][1010],mxv[1010][1010];

void min_horiz(int i, int A) {
    deque<int> d;
    for(int j=1;j<=M;++j) {
        while(!d.empty() && a[i][j] <= a[i][d.back()]) {
            d.pop_back();
        }
        d.push_back(j);
        if(j>=A) {
            mnh[i][j-A+1]=a[i][d.front()];
        }
        if(j-d.front() >= A-1) {
            d.pop_front();
        }
    }
}

void max_horiz(int i, int A) {
    deque<int> d;
    for(int j=1;j<=M;++j) {
        while(!d.empty() && a[i][j] >= a[i][d.back()]) {
            d.pop_back();
        }
        d.push_back(j);
        if(j>=A) {
            mxh[i][j-A+1]=a[i][d.front()];
        }
        if(j-d.front() >= A-1) {
            d.pop_front();
        }
    }
}

void min_vert(int j, int B) {
    deque<int> d;
    for(int i=1;i<=N;++i) {
        while(!d.empty() && mnh[i][j] <= mnh[d.back()][j]) {
            d.pop_back();
        }
        d.push_back(i);
        if(i>=B) {
            mnv[i-B+1][j] = mnh[d.front()][j];
        }
        if(i-d.front() >= B-1) {
            d.pop_front();
        }
    }
}

void max_vert(int j, int B) {
    deque<int> d;
    for(int i=1;i<=N;++i) {
        while(!d.empty() && mxh[i][j] >= mxh[d.back()][j]) {
            d.pop_back();
        }
        d.push_back(i);
        if(i>=B) {
            mxv[i-B+1][j] = mxh[d.front()][j];
        }
        if(i-d.front() >= B-1) {
            d.pop_front();
        }
    }
}

void show() {
    for(int i=1;i<=N-B+1;++i) {
        for(int j=1;j<=M-A+1;++j) {
            printf("%d ",mxv[i][j]);
        }
        printf("\n");
    }
}

void solve(int A, int B) {

    rez = 9000;
    for(int i=1;i<=N;++i) {
        min_horiz(i,A); //mnh
        max_horiz(i,A); //mxh
    }

    for(int j=1;j<=M-A+1;++j) {
        min_vert(j,B); //mnv
        max_vert(j,B); //mxv
    }
    //show();

    for(int i=1;i<=N-B+1;++i) {
        for(int j=1;j<=M-A+1;++j) {
            if(mxv[i][j]-mnv[i][j] < rez) {
                rez = mxv[i][j]-mnv[i][j];
                cnt = 1;
            } else if(mxv[i][j]-mnv[i][j] == rez) {
                ++cnt;
            }
        }
    }
}

int main() {
    //freopen("input.in","r",stdin);
    freopen("struti.in","r",stdin);
    freopen("struti.out","w",stdout);
    scanf("%d%d%d",&N,&M,&P);
    for(int i=1;i<=N;++i) {
        for(int j=1;j<=M;++j) {
            scanf("%d",&a[i][j]);
        }
    }
    for(int i=1;i<=P;++i) {
        scanf("%d%d",&A,&B);
        solve(A,B);
        if(A!=B) {

            int x = rez, y = cnt;
            solve(B,A);
            if(rez==x) {
                cnt += y;
            } else if(rez>x){
                rez = x;
                cnt = y;
            }
        }
        printf("%d %d\n",rez,cnt);
    }
    return 0;
}