Cod sursa(job #2308929)

Utilizator caesar2001Stoica Alexandru caesar2001 Data 28 decembrie 2018 00:27:53
Problema Struti Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.6 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>
#include <deque>
#include <climits>

using namespace std;

class InputReader {
    public:
        InputReader() {}
        InputReader(const char *file_name) {
            input_file = fopen(file_name, "r");
            cursor = 0;
            fread(buffer, SIZE, 1, input_file);
        }
        inline InputReader &operator >>(int &n) {
            while(buffer[cursor] < '0' || buffer[cursor] > '9') {
                advance();
            }
            n = 0;
            while('0' <= buffer[cursor] && buffer[cursor] <= '9') {
                n = n * 10 + buffer[cursor] - '0';
                advance();
            }
            return *this;
        }
    private:
        FILE *input_file;
        static const int SIZE = 1 << 17;
        int cursor;
        char buffer[SIZE];
        inline void advance() {
            ++ cursor;
            if(cursor == SIZE) {
                cursor = 0;
                fread(buffer, SIZE, 1, input_file);
            }
        }
} in("struti.in");
ofstream out("struti.out");

const int NMAX = 1002;
int v[NMAX][NMAX], n, m;

pair<int, int> solve(int x, int y) {
    vector<vector<int>> mn(n + 1, vector<int> (m + 1, 0));
    vector<vector<int>> mx(n + 1, vector<int> (m + 1, 0));

    for(int i = 1; i <= n; i ++) {
        vector<int> d(m + 1, 0);
        int l = 1, r = 1;
        d[1] = 1;

        for(int j = 2; j <= m; j ++) {
            while(l <= r && v[i][d[r]] < v[i][j])
                r --;
            d[++ r] = j;
            if(j >= x)
                mx[i][j] = v[i][d[l]];
            if(d[r] - d[l] == x - 1)
                l ++;
        }

        l = 1, r = 1;
        d[1] = 1;

        for(int j = 2; j <= m; j ++) {
            while(l <= r && v[i][d[r]] > v[i][j])
                r --;
            d[++ r] = j;
            if(j >= x)
                mn[i][j] = v[i][d[l]];
            if(d[r] - d[l] == x - 1)
                l ++;
        }
    }

    vector<int> dmin(n + 1, 0);
    vector<int> dmax(n + 1, 0);
    int lmin, rmin, lmax, rmax;
    int ans = INT_MAX, cnt = 0;

    for(int j = x; j <= m; j ++) {
        lmin = 1, rmin = 1, rmax = 1, lmax = 1;
        dmin[1] = dmax[1] = 1;

        for(int i = 2; i <= n; i ++) {
            while(lmin <= rmin && mn[i][j] < mn[dmin[rmin]][j])
                rmin --;
            dmin[++ rmin] = i;

            while(lmax <= rmax && mx[i][j] > mx[dmax[rmax]][j])
                rmax --;
            dmax[++ rmax] = i;

            if(i >= y) {
               if(mx[dmax[lmax]][j] - mn[dmin[lmin]][j] < ans) {
                    ans = mx[dmax[lmax]][j] - mn[dmin[lmin]][j];
                    cnt = 0;
               }
               if(mx[dmax[lmax]][j] - mn[dmin[lmin]][j] == ans)
                    cnt ++;
            }

            if(dmin[rmin] - dmin[lmin] == y - 1)
                lmin ++;
            if(dmax[rmax] - dmax[lmax] == y - 1)
                lmax ++;
        }
    }

    return {ans, cnt};
}

int main() {
    int p;
    in >> n >> m >> p;
    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= m; j ++)
            in >> v[i][j];

    while(p --) {
        int dx, dy;
        in >> dx >> dy;
        auto a = solve(dx, dy);
        auto b = solve(dy, dx);

        if(a.first == b.first && dx != dy)
            a.second += b.second;
        if(a.first > b.first)
            swap(a, b);
        out << a.first << " " << a.second << "\n";
    }

    return 0;
}