Cod sursa(job #1655700)

Utilizator atatomirTatomir Alex atatomir Data 18 martie 2016 11:15:40
Problema Struti Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.34 kb
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>
#include <queue>
#include <assert.h>

using namespace std;

#define mp make_pair
#define pb push_back
#define ll long long

#define maxN 1024

template<typename T>
struct min_window {
    deque< pair<int, T> > data;

    void init() { data.clear(); }

    void operator<<(pair<int, T> act) {
        while (!data.empty()) {
            auto last = data.back();
            if (last.second < act.second) break;
            data.pop_back();
        }
        data.push_back(act);
    }

    void remove_until(int limit) {
        while (!data.empty()) {
            auto last = data.front();
            if (last.first >= limit) break;
            data.pop_front();
        }
    }

    pair<int, T> query() {
        assert(data.empty() == false);
        return data.front();
    }
};


template<typename T>
struct max_window {
    deque< pair<int, T> > data;

    void init() { data.clear(); }

    void operator<<(pair<int, T> act) {
        while (!data.empty()) {
            auto last = data.back();
            if (last.second > act.second) break;
            data.pop_back();
        }
        data.push_back(act);
    }

    void remove_until(int limit) {
        while (!data.empty()) {
            auto last = data.front();
            if (last.first >= limit) break;
            data.pop_front();
        }
    }

    pair<int, T> query() {
        assert(data.empty() == false);
        return data.front();
    }
};





int n, m, i, j, p, dx, dy;
int mat[maxN][maxN];
int min_work[maxN][maxN], max_work[maxN][maxN];
min_window<int> wmin;
max_window<int> wmax;


pair<int, int> solve() {
    int i, j;
    int ans = 8001;
    int cnt = 0;

    for (i = 1; i <= n; i++) {
        wmin.init();
        wmax.init();

        for (j = 1; j <= m; j++) {
            wmin << mp(j, mat[i][j]);
            wmax << mp(j, mat[i][j]);

            wmin.remove_until(j - dy + 1);
            wmax.remove_until(j - dy + 1);

            min_work[i][j] = wmin.query().second;
            max_work[i][j] = wmax.query().second;
        }
    }

    for (j = dy; j <= m; j++) {
        wmin.init();
        wmax.init();

        for (i = 1; i <= n; i++) {
            wmin << mp(i, min_work[i][j]);
            wmax << mp(i, max_work[i][j]);

            wmin.remove_until(i - dx + 1);
            wmax.remove_until(i - dx + 1);

            if (i >= dx) {
                int aux =  wmax.query().second - wmin.query().second;

                if (aux < ans) {
                    ans = aux;
                    cnt = 0;
                }

                if (aux == ans)
                    cnt++;
            }
        }
    }



    return mp(ans, cnt);
}


int main()
{
    freopen("struti.in","r",stdin);
    freopen("struti.out","w",stdout);

    scanf("%d%d%d", &n, &m, &p);
    for (i = 1; i <= n; i++)
        for (j = 1; j <= m; j++)
            scanf("%d", &mat[i][j]);

    for (i = 1; i <= p; i++) {
        scanf("%d%d", &dx, &dy);

        auto ans1 = solve();
        auto ans2 = mp(8001, 0);

        if (dx != dy) {
            swap(dx, dy);
            ans2 = solve();
        }

        if (ans1.first > ans2.first) swap(ans1, ans2);
        if (ans1.first == ans2.first)
            ans1.second += ans2.second;

        printf("%d %d\n", ans1.first, ans1.second);
    }


    return 0;
}