Cod sursa(job #1993792)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 23 iunie 2017 19:21:14
Problema Struti Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.35 kb
#include <fstream>

using namespace std;

ofstream fout ("struti.out");

class InputReader {
	public:
        InputReader() {}
        InputReader(const char *name) {
            fin = fopen(name, "r");
			buffpos = Size - 1;
        }
        inline InputReader &operator >>(short int &n) {
			char ch = nextpos();
            while((ch < '0' || ch > '9') && ch != '-') {
                ch = nextpos();
            }

            n = 0;
            while('0' <= ch && ch <= '9') {
                n = n * 10 + ch - '0';
                ch = nextpos();
            }
            return *this;
        }
    private:
        FILE *fin;
        static const int Size = 1 << 17;
        int buffpos;
        char buff[Size];

        inline char nextpos() {
            ++ buffpos;
            if(buffpos == Size) {
                buffpos = 0;
                fread(buff, Size, 1, fin);
            }
			return buff[ buffpos ];
        }
} fin ("struti.in");

typedef short int i16;

const int nmax = 1000 + 5;
const int inf = 1 << 30;

i16 n, m;
i16 v[nmax + 1][nmax + 1];

pair<i16, i16> mx[nmax + 1], mn[nmax + 1], mncol[nmax + 1][nmax + 1], mxcol[nmax + 1][nmax + 1];

void baga_minim (pair<i16, i16> d[nmax + 1], i16 val, i16 pos, i16 lg) {
    while (d[ 0 ].first <= d[ 0 ].second && d[ d[ 0 ].second ].first >= val) {
        -- d[ 0 ].second;
    }
    d[ ++ d[ 0 ].second ] = make_pair(val, pos);

    if (d[ d[ 0 ].first ].second <= pos - lg) {
        ++ d[ 0 ].first;
    }
}

void baga_maxim (pair<i16, i16> d[nmax + 1], i16 val, i16 pos, i16 lg) {
    while (d[ 0 ].first <= d[ 0 ].second && d[ d[ 0 ].second ].first <= val) {
        -- d[ 0 ].second;
    }
    d[ ++ d[ 0 ].second ] = make_pair(val, pos);

    if (d[ d[ 0 ].first ].second <= pos - lg) {
        ++ d[ 0 ].first;
    }
}

pair<i16, i16> solve (i16 x, i16 y) {
    for (int i = 1; i <= m; ++ i) {
        mncol[ i ][ 0 ] = make_pair(1, 0);
        mxcol[ i ][ 0 ] = make_pair(1, 0);
    }

    int sol, cate;
    sol = inf; cate = 0;
    for (int i = 1; i <= n; ++ i) {
        for (int j = 1; j <= m; ++ j) {
            baga_minim(mncol[ j ], v[ i ][ j ], i, x);
            baga_maxim(mxcol[ j ], v[ i ][ j ], i, x);
        }

        mn[ 0 ] = make_pair(1, 0);
        mx[ 0 ] = make_pair(1, 0);

        for (int j = 1; j <= m; ++ j) {
            baga_minim(mn, mncol[ j ][ mncol[ j ][ 0 ].first ].first, j, y);
            baga_maxim(mx, mxcol[ j ][ mxcol[ j ][ 0 ].first ].first, j, y);

            if (x <= i && y <= j) {
                int dif = mx[ mx[ 0 ].first ].first - mn[ mn[ 0 ].first ].first;
                if (dif < sol) {
                    sol = dif; cate = 0;
                }
                cate += (dif == sol);
            }
        }
    }

    return make_pair(sol, cate);
}

int main() {
    i16 q;
    fin >> n >> m >> q;
    for (int i = 1; i <= n; ++ i) {
        for (int j = 1; j <= m; ++ j) {
            fin >> v[ i ][ j ];
        }
    }

    while (q --) {
        i16 x, y;
        fin >> x >> y;

        pair<i16, i16> ans1 = solve(x, y);
        if (x != y) {
            pair<i16, i16> ans2 = solve(y, x);

            if (ans1.first == ans2.first) {
                ans1.second += ans2.second;
            } else if (ans1.first > ans2.first) {
                ans1 = ans2;
            }
        }

        fout << ans1.first << " " << ans1.second << "\n";
    }

    fout.close();
    return 0;
}