Cod sursa(job #2807490)

Utilizator BlueLuca888Girbovan Robert Luca BlueLuca888 Data 23 noiembrie 2021 20:54:43
Problema Struti Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.5 kb
#include <bits/stdc++.h>
#define srt short

using namespace std;

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

const int DIM = 500;

srt mat[DIM][DIM], rmq[9][9][DIM][DIM], RMQ[9][9][DIM][DIM], lg2[DIM];
int n, m, q, a, b, minn, sol;

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

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

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

void calc_rmq2(){
    ///initializare
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            rmq[0][0][i][j] = mat[i][j],
            RMQ[0][0][i][j] = mat[i][j];

    int ii, jj, nn=lg2[n], mm=lg2[m];
    for(int pi=0; pi<=nn; pi++) ///pana la log2(n)
        for(int pj=0; pj<=mm; pj++) ///pana la log2(m)
            if(pi || pj)
                for(int i=1; (ii = i + (1 << pi) - 1) <= n; i++)///ii <= n
                    for(int j=1; (jj = j + (1 << pj) - 1) <= m; j++)///jj <= m
                        rmq[pi][pj][i][j] = getMin(i, j, ii, jj),
                        RMQ[pi][pj][i][j] = getMax(i, j, ii, jj);
}

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

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

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

int main (){
    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_rmq2();

    /**
    4x4
    1 4 3 2
    5 4 8 9
    3 8 5 8
    2 0 6 4
    **/
    //cout<<getMin(1, 2, 2, 4); // 1

    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;
}