Cod sursa(job #2412013)

Utilizator alex2kamebossPuscasu Alexandru alex2kameboss Data 21 aprilie 2019 15:57:07
Problema Struti Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.78 kb
#include <iostream>
#include <cstdio>
#include <deque>

#define N 1005

using namespace std;

int n,m,t;
int a[N][N];
int sol, nr;
deque <pair<int,int>> lmin, lmax;

struct Arbore{
    pair<int,int> *arbint;
    int c;
    Arbore(){
        ;
    }
    Arbore(int col){
        arbint = new pair<int,int>[4*n];
        c = col;
        construieste(1,n,1);
    }

    void construieste(int st, int dr, int pos){
        if(st == dr){
            arbint[pos] = {a[st][c],a[st][c]};
            return ;
        }

        int mij = (st+dr)/2;

        construieste(st,mij,2*pos);
        construieste(mij+1,dr,2*pos+1);

        arbint[pos] = {min(arbint[2*pos].first,arbint[2*pos+1].first),
                        max(arbint[2*pos].second, arbint[2*pos+1].second)};
    }

    pair<int,int> cauta(int st, int dr){
        return cauta(st,dr,1,n,1);
    }

    pair<int,int> intersectie(pair<int,int> st, pair<int,int> dr){
        return {min(st.first,dr.first),
                max(st.second, dr.second)};
    }

    pair<int,int> cauta(int qst, int qdr, int st, int dr, int pos){
        if(qst<=st && dr<=qdr)
            return arbint[pos];

        int mij = (st+dr)/2;

        if(qdr<=mij)
            return cauta(qst,qdr,st,mij,2*pos);
        if(mij<qst)
            return cauta(qst,qdr,mij+1,dr,2*pos+1);
        return intersectie(cauta(qst,qdr,st,mij,2*pos),
                cauta(qst,qdr,mij+1,dr,2*pos+1));
    }
}arb[N];

void adauga(int i, pair<int,int> val, int d){
    while(!lmin.empty() && lmin.back().first>val.first)
        lmin.pop_back();
    lmin.push_back({val.first,i});
    if(i-lmin.front().second+1>d)
        lmin.pop_front();

    while(!lmax.empty() && lmax.back().first<val.second)
        lmax.pop_back();
    lmax.push_back({val.second,i});
    if(i-lmax.front().second+1>d)
        lmax.pop_front();
}

void solve(int dx, int dy){
    for(int i = 1; i <= n-dx+1; ++i){
        lmin.clear();
        lmax.clear();
        for(int j = 1; j <= m; ++j){
            adauga(j,arb[j].cauta(i,i+dx-1),dy);
            if(j>=dy){
                int dif = lmax[0].first - lmin[0].first;
                if(dif==sol)
                    ++nr;
                else if(dif<sol){
                    sol = dif;
                    nr = 1;
                }
            }
        }
    }
}

int main()
{
    freopen("struti.in","r",stdin);
    freopen("struti.out","w",stdout);

    scanf("%d%d%d", &n,&m,&t);
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
            scanf("%d", &a[i][j]);

    for(int i = 1; i <= n; ++i)
        arb[i] = Arbore(i);

    int dx,dy;
    for(int i = 0; i < t; ++i){
        scanf("%d%d", &dx,&dy);
        sol = 10000;
        nr = 0;
        solve(dx,dy);
        if(dx!=dy)
            solve(dy,dx);
        cout<<sol<<" "<<nr<<"\n";
    }

    return 0;
}