Cod sursa(job #2805373)

Utilizator BlueLuca888Girbovan Robert Luca BlueLuca888 Data 21 noiembrie 2021 14:27:48
Problema Struti Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.32 kb
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")

using namespace std;

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

const int DIM = 1005;

int rmq[DIM][11][DIM][11];
int RMQ[DIM][11][DIM][11];
int lg2[DIM];

int n, m, q, minn, sol;
int h[DIM][DIM];

void _min(int &a, int b){
    a=min(a, b);
}

void _max(int &a, int b){
    a=max(a, b);
}

void calc_rmq_2D(){
    int ii, jj;

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

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

        for(int pj=1; pj<=lg2[m]; pj++)
            for(int j=1; j<=m; j++){

                rmq[i][0][j][pj] = rmq[i][0][j][pj-1];
                RMQ[i][0][j][pj] = RMQ[i][0][j][pj-1];

                jj = j + (1 << (pj-1));
                if(jj <= m)
                    _min(rmq[i][0][j][pj], rmq[i][0][jj][pj-1]), _max(RMQ[i][0][j][pj], RMQ[i][0][jj][pj-1]);
            }
    }

    for(int pi=1; pi<=lg2[n]; pi++)
        for(int i=1; i<=n; i++)
            for(int pj=0; pj<=lg2[m]; pj++)
                for(int j=1; j<=m; j++){
                    rmq[i][pi][j][pj] = rmq[i][pi-1][j][pj];
                    RMQ[i][pi][j][pj] = RMQ[i][pi-1][j][pj];

                    ii = i + (1<<(pi-1));
                    if(ii <= n && jj <= m)
                        _min(rmq[i][pi][j][pj], rmq[ii][pi-1][j][pj]), _max(RMQ[i][pi][j][pj], RMQ[ii][pi-1][j][pj]);
                }
}

int getMin(int x, int y, int xx, int yy){
    int lx = xx - x + 1;
    int ly = yy - y + 1;
    int kx = lg2[lx];
    int ky = lg2[ly];

    int aux = INT_MAX;

    _min(aux, rmq[x][kx][y][ky]);
    _min(aux, rmq[x][kx][yy-(1<<ky)+1][ky]);
    _min(aux, rmq[xx-(1<<kx)+1][kx][y][ky]);
    _min(aux, rmq[xx-(1<<kx)+1][kx][yy-(1<<ky)+1][ky]);

    return aux;
}

int getMax(int x, int y, int xx, int yy){
    int lx = xx - x + 1;
    int ly = yy - y + 1;
    int kx = lg2[lx];
    int ky = lg2[ly];

    int aux = INT_MIN;

    _max(aux, RMQ[x][kx][y][ky]);
    _max(aux, RMQ[x][kx][yy-(1<<ky)+1][ky]);
    _max(aux, RMQ[xx-(1<<kx)+1][kx][y][ky]);
    _max(aux, RMQ[xx-(1<<kx)+1][kx][yy-(1<<ky)+1][ky]);

    return aux;
}

void solve(int a, int b){
    int x, y, xx, yy, mx, mn, dif;
    for(x=1; x<=n; x++)
        for(y=1; y<=m; y++){
            xx = x + a - 1;
            yy = y + b - 1;

            if(xx > n || yy > m)
                break;

            ///dreptunghiul (x, y), (xx, yy)
            mn = getMin(x, y, xx, yy);
            mx = getMax(x, y, xx, yy);

            dif = mx - mn;
            if(dif < minn){
                minn = dif;
                sol = 1;
            }else if(dif == 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>>h[i][j];

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

    calc_rmq_2D();

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

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