Cod sursa(job #2085226)

Utilizator andreicoman299Coman Andrei andreicoman299 Data 9 decembrie 2017 20:32:01
Problema Struti Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.59 kb
#include <bits/stdc++.h>
#define MAXN 1000

#define BUF_SIZE 1 << 14
char buf[BUF_SIZE];
int pbuf=BUF_SIZE;
FILE*fi,*fo;
inline char nextch(){
    if(pbuf==BUF_SIZE){
        fread(buf, BUF_SIZE, 1, fi);
        pbuf=0;
    }
    return buf[pbuf++];
}
inline int nextnum(){
    int a = 0;
    char c = nextch();
    while(!isdigit(c))
        c = nextch();
    while(isdigit(c)){
        a = a * 10 + c - '0';
        c = nextch();
    }
    return a;
}

class deque{
    public:
    int v[1 + MAXN];
    int p = 0, u = -1;

    int empty(){
        return p > u;
    }
    void push_back(int val){
        v[++u] = val;
    }
    void pop_back(){
        if(u >= p)
            u--;
    }
    void pop_front(){
        if(p <= u)
            p++;
    }
    void clear(){
        p = 0;
        u = -1;
    }
    int front(){
        return v[p];
    }
    int back(){
        return v[u];
    }
};

int m, n;
struct Ans{
    int min, nr;
};
int v[1 + MAXN][1 + MAXN];
deque d[1 + MAXN];
deque D[1 + MAXN];
deque min, max;

inline Ans Compute(int dx, int dy){
    Ans ans;
    ans.min = 1000000000;

    for(int i = 1; i <= m; i++){
        d[i].clear();
        D[i].clear();
    }
    for(int j = 1; j <= n; j++){
        min.clear();
        max.clear();
        for(int i = 1; i <= m; i++){
            //minim
            while(!d[i].empty() && j - d[i].front() + 1 > dx)
                d[i].pop_front();
            while(!d[i].empty() && v[i][d[i].back()] > v[i][j])
                d[i].pop_back();
            d[i].push_back(j);
            //maxim
            while(!D[i].empty() && j - D[i].front() + 1 > dx)
                D[i].pop_front();
            while(!D[i].empty() && v[i][D[i].back()] < v[i][j])
                D[i].pop_back();
            D[i].push_back(j);

            //minim
            while(!min.empty() && i - min.front() + 1 > dy)
                min.pop_front();
            while(!min.empty() && v[min.back()][d[min.back()].front()] > v[i][d[i].front()])
                min.pop_back();
            min.push_back(i);
            //maxim
            while(!max.empty() && i - max.front() + 1 > dy)
                max.pop_front();
            while(!max.empty() && v[max.back()][D[max.back()].front()] < v[i][D[i].front()])
                max.pop_back();
            max.push_back(i);

            int minval = v[min.front()][d[min.front()].front()];
            int maxval = v[max.front()][D[max.front()].front()];
            if(i >= dy && j >= dx){
                if(maxval - minval < ans.min){
                    ans.min = maxval - minval;
                    ans.nr = 0;
                }
                if(maxval - minval == ans.min)
                    ans.nr++;
            }
        }
    }

    return ans;
}

int main(){
    fi=fopen("struti.in","r");
    fo=fopen("struti.out","w");

    int p;
    m = nextnum(), n = nextnum(), p = nextnum();
    for(int i = 1; i <= m; i++)
        for(int j = 1; j <= n; j++)
            v[i][j] = nextnum();
    for(int i = 1; i <= p; i++){
        int dx = nextnum(), dy = nextnum();
        Ans a = Compute(dx, dy);
        Ans b = Compute(dy, dx);
        if(dx == dy)
            fprintf(fo,"%d %d\n", a.min, a.nr);
        else{
            if(a.min < b.min)
                fprintf(fo,"%d %d\n", a.min, a.nr);
            else if(a.min == b.min)
                fprintf(fo,"%d %d\n", a.min, a.nr + b.nr);
            else
                fprintf(fo,"%d %d\n", b.min, b.nr);
        }
    }

    fclose(fi);
    fclose(fo);
    return 0;
}