Cod sursa(job #1076981)

Utilizator narcis_vsGemene Narcis - Gabriel narcis_vs Data 10 ianuarie 2014 19:40:01
Problema Struti Scor 20
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 2.9 kb
#include <cstdio>
#include <fstream>
#include <deque>
#include <vector>
#define LIM 5000000
#define NEXT ++pos == LIM ? f.read(Buffer,LIM),pos = 0 : 0
using namespace std;

#define MAXN 104

int N, M, A, B;
int m[MAXN][MAXN];
ifstream f("struti.in");
ofstream g("struti.out");
char Buffer[LIM];
int pos;
inline void Read(int &x){
    for( ; Buffer[pos] < '0' || '9' < Buffer[pos]; NEXT);
    for(x = 0 ;'0' <= Buffer[pos] && Buffer[pos] <= '9'; NEXT)
        x = x * 10 + Buffer[pos]-'0';
}
class Deque{
private:
    int max_elem, cur_elem;
    deque<pair<int, int> > elem, elem2;
public:
    Deque(int max_elements){
        max_elem = max_elements;
        cur_elem = 0;
    }

    void add_element(int value, int value2=-1){
        cur_elem += 1;
        if (value2 == -1)
            value2 = value;

        for (; !elem.empty() && value > elem.back().first; )
            elem.pop_back();
        elem.push_back(make_pair(value, cur_elem));
        if (elem.back().second - elem.front().second + 1 > max_elem)
            elem.pop_front();

        for (; !elem2.empty() && value2 < elem2.back().first; )
            elem2.pop_back();
        elem2.push_back(make_pair(value2, cur_elem));
        if (elem2.back().second - elem2.front().second + 1 > max_elem)
            elem2.pop_front();
    }

    int min_element(){
        return elem2.front().first;
    }
    int max_element(){
        return elem.front().first;
    }

    int diff(){
        return elem.front().first - elem2.front().first;
    }
};

inline int solve(int A, int B, int &Nr){
    int REZ = 0x3f3f3f3f;
    Nr = 0;
    vector<Deque> deques(M, Deque(A));

    for (int i = 0; i < N; i++){
        for (int j = 0; j < M; j++)
            deques[j].add_element(m[i][j]);

        if (i < A - 1)
            continue;

        Deque big_deque(B);
        for (int j = 0; j < M; j++){
            big_deque.add_element(deques[j].max_element(), deques[j].min_element());

            if (j < B - 1)
                continue;
            int val = big_deque.diff();
            if (val < REZ)
                REZ = val,
                Nr = 1;
            else
                if (val == REZ)
                    Nr += 1;
        }
    }
    return REZ;
}

int main()
{
        freopen("struti.in", "rt", stdin);
    freopen("struti.out", "wt", stdout);
    f.read(Buffer,LIM);
    int T;
    Read(N);Read(M);Read(T);
    scanf("%d %d %d", &N, &M, &T);
    for (int i = 0; i < N; ++i)
        for (int j = 0; j < M; ++j)
            Read(m[i][j]);

    for (; T; --T){
        Read(A);Read(B);
        int rez, nr;
        if (A == B)
            rez = solve(A, A, nr);
        else{
            int rez2, nr2;
            rez = solve(A, B, nr);
            rez2 = solve(B, A, nr2);
            if (rez == rez2)
                nr += nr2;
            if (rez2 < rez)
                rez = rez2,
                nr = nr2;
        }
        printf("%d %d\n", rez, nr);
    }

    return 0;
}