Cod sursa(job #2455107)

Utilizator Senth30Denis-Florin Cringanu Senth30 Data 10 septembrie 2019 19:48:33
Problema Struti Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.18 kb
#include <bits/stdc++.h>
#define MAX 131072

using namespace std;
const int NMAX = 1010;

FILE *IN;

int ans, nrplace;
int N, M, P;
int mat[NMAX][NMAX];

deque <int> dmin[NMAX], dmax[NMAX];
deque <pair <int, int> > ansMin, ansMax;

int pos, sign;
char f[MAX];

inline void Read(int &nr){
    sign = 0;
    nr = 0;
    while(f[pos] < '0' || f[pos] > '9'){
        if(f[pos] == '-') sign = 1;
        pos++;
        if(pos == MAX)
            fread(f, MAX, 1, IN), pos = 0;
    }
    while(f[pos] >= '0' && f[pos] <= '9'){
        nr = 10 * nr + f[pos++] - '0';
        if(pos == MAX)
            fread(f, MAX, 1, IN), pos = 0;
    }
    if(sign) nr =- nr;
}

inline void read(){
    Read(N); Read(M); Read(P);
    for(int i = 1; i <= N; i++)
        for(int j = 1; j <= M; j++)
            Read(mat[i][j]);
}

inline void add_element_max(int x, int i, int lgmax, int poz){
    if(poz - dmax[i].front() >= lgmax)
        dmax[i].pop_front();
    while(dmax[i].size() > 0 && mat[i][dmax[i].back()] < x)
        dmax[i].pop_back();
    dmax[i].push_back(poz);
}

inline void add_element_min(int x, int i, int lgmax, int poz){
    if(poz - dmin[i].front() >= lgmax)
        dmin[i].pop_front();
    while(dmin[i].size() > 0 && mat[i][dmin[i].back()] > x)
        dmin[i].pop_back();
    dmin[i].push_back(poz);
}

inline void find_ansMin(int x, int poz, int lgmax){
    if(poz - ansMin.front().second >= lgmax)
        ansMin.pop_front();
    while(ansMin.size() > 0 && ansMin.back().first > x)
        ansMin.pop_back();
    ansMin.push_back(make_pair(x, poz));
}

inline void find_ansMax(int x, int poz, int lgmax){
    if(poz - ansMax.front().second >= lgmax)
        ansMax.pop_front();
    while(ansMax.size() > 0 && ansMax.back().first < x)
        ansMax.pop_back();
    ansMax.push_back(make_pair(x, poz));
}

inline void solve(int x, int y){
    for(int j = 1; j <= M; j++){
        for(int i = 1; i <= N; i++){
            add_element_max(mat[i][j], i, x, j);
            add_element_min(mat[i][j], i, x, j);
        }
        if(j >= x){
            for(int i = 1; i <= N; i++){
                find_ansMin(mat[i][dmin[i].front()], i, y);
                find_ansMax(mat[i][dmax[i].front()], i, y);
                if(i >= y){
                    if(ansMax.front().first - ansMin.front().first < ans)
                        ans = ansMax.front().first - ansMin.front().first, nrplace = 1;
                    else if(ansMax.front().first - ansMin.front().first == ans)
                        nrplace++;
                }
            }
            while(!ansMin.empty()) ansMin.pop_back();
            while(!ansMax.empty()) ansMax.pop_back();
        }
    }

    for(int i = 1; i <= N; i++){
        while(!dmin[i].empty()) dmin[i].pop_back();
        while(!dmax[i].empty()) dmax[i].pop_back();
    }
}

int main(){

    IN = fopen("struti.in", "r");
    freopen("struti.out", "w", stdout);

    read();

    int x, y;
    for(int i = 1; i <= P; i++){
        ans = 2e9; nrplace = 0;
        Read(x); Read(y);
        solve(x, y);
        if(x != y) solve(y, x);
        printf("%d %d\n", ans, nrplace);
    }

    return 0;
}