Cod sursa(job #2015032)

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

using namespace std;
const int inf = 1e9 + 5;
const int NMax = 1e3 + 5;

class parser {
    using integer = int;
    static const int strMax = 6*NMax*NMax + 50;

    ifstream in;
    char str[strMax],*p;
    bool failed;

    public:
    parser(string s) {
        in.open(s);
        in.get(str,strMax,1);
        p = str;
        failed = false;
    }

    parser& operator>> (integer& nr) {
        bool neg = 0;
        while ( !( ('0' <= *p && *p <= '9') || *p == '\0') ) {
            if (*p == '-') {
                neg ^= 1;
            }
            ++p;
        }

        if (*p == '\0') {
            nr = 0;
            failed = true;
            return *this;
        }

        nr = 0;
        while ('0' <= *p && *p <= '9') {
            nr = nr * 10 + *p++ - '0';
        }
        if (neg) {nr = -nr;}

        return *this;
    }

    bool fail() {
        return failed;
    }

    void print() {
        cout<<str<<'\n';
    }

    void close() {
        in.close();
    }
};
parser pin("struti.in");
ofstream out("struti.out");

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

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

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

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

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

        zint min1,nrMin1,min2,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';
    }

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

void solve(zint dx,zint dy,zint& mn,zint& nrMin) {
    deque<zint> 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() && a[i][rowMn[i].back()] >= a[i][j]) {
                rowMn[i].pop_back();
            }
            rowMn[i].push_back(j);
            if (rowMn[i].front() == j-dy) {
                rowMn[i].pop_front();
            }

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

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

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

            for (int i=1;i <= N;++i) {

                while (colMn.size() && a[colMn.back()][rowMn[colMn.back()].front()] >= a[i][rowMn[i].front()]) {
                    colMn.pop_back();
                }
                colMn.push_back(i);
                if (colMn.front() == i-dx) {
                    colMn.pop_front();
                }

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

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

                if (i >= dx) {
                    int val = a[colMx.front()][rowMx[colMx.front()].front()] -
                              a[colMn.front()][rowMn[colMn.front()].front()];
                    if (mn > val) {
                        mn = val;
                        nrMin = 1;
                    }
                    else if (mn == val) {
                        ++nrMin;
                    }
                }
            }
        }
    }

}