Cod sursa(job #2015574)

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

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

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

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

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

    parser& operator>> (integer& nr) {
        while ( !( ('0' <= *p && *p <= '9') || *p == '\0') ) {
            ++p;
        }

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

        return *this;
    }
    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 = short;

zint N,M,P;
zint a[NMax][NMax];
pair<int,int> colMn[NMax][NMax],colMx[NMax][NMax],rowMn[NMax],rowMx[NMax];
const pair<int,int> def = pair<int,int>(1,0);

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

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,min1,min2;
        int nrMin1,nrMin2;
        pin>>dx>>dy;

        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,int& nrMin) {
    for (int j=1;j <= M;++j) {
        colMn[j][0] = def;
        colMx[j][0] = def;
    }

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

            while (colMn[j][0].first <= colMn[j][0].second && colMn[j][ colMn[j][0].second ].second >= a[i][j]) {
                --colMn[j][0].second;
            }
            colMn[j][ ++colMn[j][0].second ] = make_pair(i,a[i][j]);
            if (colMn[j][ colMn[j][0].first ].first == i-dx) {
                ++colMn[j][0].first;
            }

            while (colMx[j][0].first <= colMx[j][0].second && colMx[j][ colMx[j][0].second ].second <= a[i][j]) {
                --colMx[j][0].second;
            }
            colMx[j][ ++colMx[j][0].second ] = make_pair(i,a[i][j]);
            if (colMx[j][ colMx[j][0].first ].first == i-dx) {
                ++colMx[j][0].first;
            }

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

        if (i >= dx) {
            rowMn[0] = rowMx[0] = def;

            for (int j=1;j <= M;++j) {

                while (rowMn[0].first <= rowMn[0].second && rowMn[ rowMn[0].second ].second >= colMn[j][ colMn[j][0].first].second) {
                    --rowMn[0].second;
                }
                rowMn[ ++rowMn[0].second ] = make_pair(j,colMn[j][ colMn[j][0].first ].second);
                if (rowMn[ rowMn[0].first ].first == j-dy) {
                    ++rowMn[0].first;
                }

                while (rowMx[0].first <= rowMx[0].second && rowMx[ rowMx[0].second ].second <= colMx[j][ colMx[j][0].first].second) {
                    --rowMx[0].second;
                }
                rowMx[ ++rowMx[0].second ] = make_pair(j,colMx[j][ colMx[j][0].first ].second);
                if (rowMx[ rowMx[0].first ].first == j-dy) {
                    ++rowMx[0].first;
                }

                //cout<<i<<' '<<rowMn.front()<<' '<<rowMx.front()<<"\n\n\n";

                if (j >= dy) {
                    short val = rowMx[ rowMx[0].first ].second - rowMn[ rowMn[0].first ].second;
                    //cout<<val<<"\n\n\n";
                    if (mn > val) {
                        mn = val;
                        nrMin = 1;
                    }
                    else if (mn == val) {
                        ++nrMin;
                    }
                }
            }
        }
    }

}