Cod sursa(job #2017739)

Utilizator MaligMamaliga cu smantana Malig Data 2 septembrie 2017 12:37:59
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.81 kb
#include <iostream>
#include <fstream>
#include <stack>
#include <vector>
#include <deque>
#include <ctime>
#include <queue>

#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
using zint = short;
using namespace std;
const int inf = 3e4 + 5;
const int NMax = 1e3 + 5;
const pair<zint,zint> def = mp(1,0);
ifstream in("struti.in");
ofstream out("struti.out");

zint N,M,P;
zint a[NMax][NMax],rowMn[NMax][NMax],rowMx[NMax][NMax];
pair<zint,zint> dmn[NMax],dmx[NMax];

void solve(zint,zint,zint&,ll&);
void pushMin(pair<zint,zint>*, pair<zint,zint>, zint);
void pushMax(pair<zint,zint>*, pair<zint,zint>, zint);

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

        solve(dx,dy,min1,nrMin1);
        if (dx != dy) {
            solve(dy,dx,min2,nrMin2);

            if (min1 == min2) {
                nrMin1 += nrMin2;
            }
            else if (min1 > min2) {
                min1 = min2;
                nrMin1 = nrMin2;
            }
        }

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

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

void solve(zint dx,zint dy,zint& mn,ll& nrMin) {
    for (zint i=1;i <= N;++i) {
        dmn[0] = dmx[0] = def;
        for (zint j=1;j <= M;++j) {
            pushMin(dmn,mp(j,a[i][j]),dy);
            pushMax(dmx,mp(j,a[i][j]),dy);

            rowMn[i][j] = dmn[ dmn[0].first ].second;
            rowMx[i][j] = dmx[ dmx[0].first ].second;
        }
    }

    mn = inf, nrMin = -1;
    for (zint j=dy;j <= M;++j) {
        dmn[0] = dmx[0] = def;
        for (zint i=1;i <= N;++i) {
            pushMin(dmn,mp(i,rowMn[i][j]),dx);
            pushMax(dmx,mp(i,rowMx[i][j]),dx);

            if (i >= dx) {
                zint val = dmx[ dmx[0].first ].second - dmn[ dmn[0].first ].second;
                if (mn > val) {
                    mn = val;
                    nrMin = 1;
                }
                else if (mn == val) {
                    ++nrMin;
                }
            }
        }
    }
}

void pushMin(pair<zint,zint> *d, pair<zint,zint> el, zint len) {
    while (d[0].first <= d[0].second && d[ d[0].second ].second >= el.second) {
        --d[0].second;
    }
    d[ ++d[0].second ] = el;
    if (d[ d[0].first ].first == el.first - len) {
        ++d[0].first;
    }
}

void pushMax(pair<zint,zint> *d, pair<zint,zint> el, zint len) {
    while (d[0].first <= d[0].second && d[ d[0].second ].second <= el.second) {
        --d[0].second;
    }
    d[ ++d[0].second ] = el;
    if (d[ d[0].first ].first == el.first - len) {
        ++d[0].first;
    }
}