Cod sursa(job #2807445)

Utilizator BlueLuca888Girbovan Robert Luca BlueLuca888 Data 23 noiembrie 2021 20:03:05
Problema Struti Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.88 kb
#include <bits/stdc++.h>

using namespace std;

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

const int DIM = 1050;

int mat[DIM][DIM];
int n, m, q, a, b, minn, sol;

int lg2[DIM], rmq[DIM][12][DIM][12], RMQ[DIM][12][DIM][12];

void calc_log2(){
    lg2[1]=0;
    for(int i=2; i < DIM; i++)
        lg2[i] = lg2[i>>1] + 1;
}

calc_rmq(){
    int lgN = lg2[n], lgM = lg2[m], ii, jj;

    //init
    for(int i=1; i<=n; i++){

        for(int j=1; j<=m; j++)
            rmq[i][0][j][0] = RMQ[i][0][j][0] = mat[i][j];

        for(int pj=1; pj<=lgM; pj++) //mergem pana la log2(m)
            for(int j=1; (jj=j+(1<<(pj-1))) <= m; j++) //jj <= m
                rmq[i][0][j][pj] = min(rmq[i][0][j][pj-1], rmq[i][0][jj][pj-1]),
                RMQ[i][0][j][pj] = max(RMQ[i][0][j][pj-1], RMQ[i][0][jj][pj-1]);
    }


    for(int pi=1; pi<=lgN; pi++) //mergem pana la log2(n)
        for(int i=1; (ii=i+(1<<(pi-1))) <= n; i++) //ii <= n
            for(int pj=0; pj<=lgM; pj++) //mergem pana la log2(m)
                for(int j=1; j <= m; j++) //mergem pana la m
                    rmq[i][pi][j][pj] = min(rmq[i][pi-1][j][pj], rmq[ii][pi-1][j][pj]),
                    RMQ[i][pi][j][pj] = max(RMQ[i][pi-1][j][pj], RMQ[ii][pj-1][j][pj]);
}

int _min(int a, int b, int c, int d){
    return min(a, min(b, min(c, d)));
}

int getMin(int i, int j, int ii, int jj){
    int pi = lg2[ii - i + 1];
    int pj = lg2[jj - j + 1];
    ii = ii - (1<<pi) + 1;
    jj = jj - (1<<pj) + 1;

    return _min(
        rmq[i][pi][j][pj],
        rmq[i][pi][jj][pj],
        rmq[ii][pi][j][pj],
        rmq[ii][pi][jj][pj]
    );
}

int _max(int a, int b, int c, int d){
    return max(a, max(b, max(c, d)));
}

int getMax(int i, int j, int ii, int jj){
    int pi = lg2[ii - i + 1];
    int pj = lg2[jj - j + 1];
    ii = ii - (1<<pi) + 1;
    jj = jj - (1<<pj) + 1;

    return _max(
        RMQ[i][pi][j][pj],
        RMQ[i][pi][jj][pj],
        RMQ[ii][pi][j][pj],
        RMQ[ii][pi][jj][pj]
    );
}

void solve(int a, int b){
    int ii, jj, mn, mx;
    for(int i=1; i<=n-a+1; i++)
        for(int j=1; j<=m-b+1; j++){
            ii = i + a - 1;
            jj = j + b - 1;

            mn = getMin(i, j, ii, jj);
            mx = getMax(i, j, ii, jj);

            if(mx - mn < minn){
                minn = mx - mn;
                sol=1;
            }else if(mx - mn == minn)
                sol++;
        }
}

int main (){
    ios_base::sync_with_stdio(false);
    fin.tie(0);
    fout.tie(0);

    fin>>n>>m>>q;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            fin>>mat[i][j];


    calc_log2();
    calc_rmq();

    while(q--){
        fin>>a>>b;
        minn = INT_MAX; sol=0;
        solve(a, b);
        if(a != b)
            solve(b, a);
        fout<<minn<<" "<<sol<<"\n";
    }
    return 0;
}