Cod sursa(job #2309579)

Utilizator caesar2001Stoica Alexandru caesar2001 Data 29 decembrie 2018 13:10:48
Problema Struti Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.65 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 ++) {
        deque<int> d;
        d.push_front(1);

        for(int j = 2; j <= m; j ++) {
            while(d.size() && v[i][d.back()] < v[i][j])
                d.pop_back();
            d.push_back(j);
            if(j >= x)
                mx[i][j] = v[i][d.front()];
            if(d.back() - d.front() == x - 1)
                d.pop_front();
        }

        d.clear();
        d.push_front(1);

        for(int j = 2; j <= m; j ++) {
            while(d.size() && v[i][d.back()] > v[i][j])
                d.pop_back();
            d.push_back(j);
            if(j >= x)
                mn[i][j] = v[i][d.front()];
            if(d.back() - d.front() == x - 1)
                d.pop_front();
        }
    }

    deque<int> dmin, dmax;
    int ans = INT_MAX, cnt = 0;

    for(int j = x; j <= m; j ++) {
        dmin.clear();
        dmin.push_front(1);
        dmax.clear();
        dmax.push_front(1);

        for(int i = 2; i <= n; i ++) {
            while(dmin.size() && mn[i][j] < mn[dmin.back()][j])
                dmin.pop_back();
            dmin.push_back(i);

            while(dmax.size() && mx[i][j] > mx[dmax.back()][j])
                dmax.pop_back();
            dmax.push_back(i);

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

            if(dmin.back() - dmin.front() == y - 1)
                dmin.pop_front();
            if(dmax.back() - dmax.front() == y - 1)
                dmax.pop_front();
        }
    }

    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;
}