Cod sursa(job #2015310)

Utilizator MaligMamaliga cu smantana Malig Data 25 august 2017 18:15:21
Problema Struti Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.36 kb
#include <iostream>
#include <fstream>
#include <stack>
#include <vector>
#include <deque>

using namespace std;
const int inf = 3e4 + 5;
const int NMax = 1e3 + 5;
ifstream in("struti.in");
ofstream out("struti.out");

#define ll long long
#define ull unsigned long long
#define pb push_back
using zint = short;

zint N,M,P;
zint a[NMax][NMax];

struct elem {
    zint idx,val;
    elem (zint _idx = 0,zint _val = 0) {
        idx = _idx;
        val = _val;
    }
};

void solve(zint,zint,zint&,int&);

int main() {
    in>>N>>M>>P;
    for (zint i=1;i <= N;++i) {
        for (zint j=1;j <= M;++j) {
            in>>a[i][j];
        }
    }

    while (P--) {
        zint dx,dy;
        in>>dx>>dy;

        zint min1,min2;
        int nrMin1,nrMin2;
        solve(dx,dy,min1,nrMin1);
        //cout<<min1<<' '<<nrMin1<<'\n';
        if (dx != dy) {
            solve(dy,dx,min2,nrMin2);
            //cout<<min2<<' '<<nrMin2<<'\n';

            if (min1 == min2) {
                nrMin1 += nrMin2;
            }
            else if (min1 > min2) {
                min1 = min2;
                nrMin1 = nrMin2;
            }
        }
        //cout<<'\n';

        out<<min1<<' '<<nrMin1<<'\n';
    }

    in.close();out.close();
    return 0;
}

void solve(zint dx,zint dy,zint& mn,int& nrMin) {
    deque<elem> rowMn[NMax],rowMx[NMax];

    mn = inf, nrMin = 0;
    for (int j=1;j <= M;++j) {
        for (int i=1;i <= N;++i) {

            while (rowMn[i].size() && rowMn[i].back().val >= a[i][j]) {
                rowMn[i].pop_back();
            }
            rowMn[i].push_back(elem(j,a[i][j]));
            if (rowMn[i].front().idx == j-dy) {
                rowMn[i].pop_front();
            }

            while (rowMx[i].size() && rowMx[i].back().val <= a[i][j]) {
                rowMx[i].pop_back();
            }
            rowMx[i].push_back(elem(j,a[i][j]));
            if (rowMx[i].front().idx == j-dy) {
                rowMx[i].pop_front();
            }

            //cout<<i<<' '<<rowMn[i].front()<<' '<<rowMx[i].front()<<'\n';
        }
        //cout<<'\n';

        if (j >= dy) {
            deque<elem> colMn,colMx;

            for (int i=1;i <= N;++i) {
                while (colMn.size() && colMn.back().val >= rowMn[i].front().val) {
                    colMn.pop_back();
                }
                colMn.push_back(elem(i,rowMn[i].front().val));
                if (colMn.front().idx == i-dx) {
                    colMn.pop_front();
                }

                while (colMx.size() && colMx.back().val <= rowMx[i].front().val) {
                    colMx.pop_back();
                }
                colMx.push_back(elem(i,rowMx[i].front().val));
                if (colMx.front().idx == i-dx) {
                    colMx.pop_front();
                }

                //cout<<i<<' '<<colMn.front()<<' '<<colMx.front()<<"\n\n\n";

                if (i >= dx) {
                    short val = colMx.front().val - colMn.front().val;
                    //cout<<val<<"\n\n\n";
                    if (mn > val) {
                        mn = val;
                        nrMin = 1;
                    }
                    else if (mn == val) {
                        ++nrMin;
                    }
                }
            }
        }
    }

}