Cod sursa(job #1081794)

Utilizator R.A.RFMI Romila Remus Arthur R.A.R Data 13 ianuarie 2014 21:48:16
Problema Struti Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.99 kb
#include <fstream>
#include <deque>

using namespace std;

const int NMAX = 1001;
const int VALMAX = 100001;

ifstream in("struti.in");
ofstream out("struti.out");

int V[NMAX][NMAX], N, M, Q;
int maxValue[NMAX][NMAX], minValue[NMAX][NMAX], bestSol, solCounter;

void calculateMaxValue(int k){ // calculeaza maximul de pe coloane intr-o matrice maxValue
    deque<int> maxL;
    int i,j;

    for (j=1; j <= N; j++){

        maxL.clear();

        for (i=1; i <= M; i++){


            while (!maxL.empty() && V[maxL.back()][j] <= V[i][j]) maxL.pop_back();
            maxL.push_back(i);

            while (!maxL.empty() && maxL.front() <= i-k) maxL.pop_front();

            if (i >= k )
                maxValue[i-k+1][j] = V[maxL.front()][j];

        }

        //for (int h=i-k; h<=m; h++)
        //  maxValue[h][j] = V[maxL.front()][j];
    }
}

void calculateMinValue(int k){
    deque<int> minL;
    int i,j;

    for (j=1; j <= N; j++){

        minL.clear();

        for (i=1; i <= M; i++){


            while (!minL.empty() && V[minL.back()][j] >= V[i][j]) minL.pop_back();
            minL.push_back(i);

            while (!minL.empty() && minL.front() <= i-k) minL.pop_front();

            if (i >= k )
                minValue[i-k+1][j] = V[minL.front()][j];

        }

    }
}

void findMinimalDifference(int x, int y){

    deque<int> maxValueDeq, minValueDeq;

    calculateMaxValue(y);
    calculateMinValue(y);

    for (int i=1; i <= N-y+1; i++){

        maxValueDeq.clear();
        minValueDeq.clear();

        for (int j=1; j <= N; j++){

            while (!minValueDeq.empty() && minValue[i][minValueDeq.back()] >= minValue[i][j]) minValueDeq.pop_back();
            minValueDeq.push_back(j);

            while (!maxValueDeq.empty() && maxValue[i][maxValueDeq.back()] <= maxValue[i][j]) maxValueDeq.pop_back();
            maxValueDeq.push_back(j);

            while (!minValueDeq.empty() && minValueDeq.front() <= j-x) minValueDeq.pop_front();
            while (!maxValueDeq.empty() && maxValueDeq.front() <= j-x) maxValueDeq.pop_front();

            if (j >= x){
                if (maxValue[i][maxValueDeq.front()] - minValue[i][minValueDeq.front()] < bestSol)
                    bestSol = maxValue[i][maxValueDeq.front()] - minValue[i][minValueDeq.front()], solCounter = 1;
                else
                    if (maxValue[i][maxValueDeq.front()] - minValue[i][minValueDeq.front()] == bestSol) solCounter++;
            }

        }

    }
}

int main(){

    int x,y;

    in >> M >> N >> Q;

    for (int i=1; i <= M; i++)
        for (int j=1; j <= N; j++)
            in >> V[i][j];

    for (int i = 1; i <= Q; i++){

        in >> x >> y;

        if (x != y){
            bestSol = VALMAX; solCounter = 0;
            findMinimalDifference(x,y);
            findMinimalDifference(y,x);

            out<<bestSol<<" "<<solCounter<<"\n";

        } else {
            bestSol = VALMAX; solCounter = 0;
            findMinimalDifference(x,y);

            out<<bestSol<<" "<<solCounter<<"\n";
        }
    }
}