Cod sursa(job #2718824)

Utilizator AACthAirinei Andrei Cristian AACth Data 9 martie 2021 11:21:19
Problema Struti Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.87 kb
#pragma GCC optimize ("Ofast")
#include <bits/stdc++.h>
using namespace std;
ifstream f("struti.in");
ofstream g("struti.out");
const int Max = 1e3 + 1;
struct minim
{
    bool operator () (int a, int b) const
    {
        return a < b;
    }
};
struct maxim
{
    bool operator () (int a, int b) const
    {
        return a > b;
    }
};
int n,m,q;
int a[Max][Max];

void read()
{
    f>>n>>m>>q;
    int i,j;
    for(i=0; i<n; i++)
        for(j=0; j<m; j++)
            f>>a[i][j];
}
int cnt;
int min_delta;
struct nod
{
    int minx;
    int maxx;
};
nod tree[Max][4*Max];
nod merge_nod(nod n1, nod n2)
{
    nod ans;
    ans.minx = min(n1.minx,n2.minx);
    ans.maxx = max(n1.maxx,n2.maxx);
    return ans;
}
int rminq[Max][Max][15];
int rmaxq[Max][Max][15];
void init_rmq(int j)
{

    int i;
    for(i=0;i<n;i++)
        rmaxq[j][i][0] = rminq[j][i][0] = a[i][j];
    for(int len = 1; (1<<len) <= n;++len)
        for(int poz = 0; poz + (1<<len) - 1 < n ; ++poz )
        rminq[j][poz][len] = min(rminq[j][poz][len-1],rminq[j][poz + (1<<(len-1))][len-1]);
    for(int len = 1; (1<<len) <= n;++len)
        for(int poz = 0; poz + (1<<len) - 1 < n ; ++poz )
        rmaxq[j][poz][len] = max(rmaxq[j][poz][len-1],rmaxq[j][poz + (1<<(len-1))][len-1]);

}
int left_limit,right_limit;
int ask_min(int j, int left, int right)
{
    int dim = log2(right - left + 1);
    return min(rminq[j][left][dim],rminq[j][right - (1<<dim) +1][dim]);

}
int ask_max(int j, int left, int right)
{
     int dim = log2(right - left + 1);
    return max(rmaxq[j][left][dim],rmaxq[j][right - (1<<dim) +1][dim]);
}


void go_on_row(int start_poz, int dimx, int dimy)
{
    multiset < int, minim > lowest;
    multiset < int, maxim > highest;
    deque < int > elemente;
    int i,j;
    for(j=0; j<=dimy; ++j)
    {
         int new_entry_min,new_entry_max;
        left_limit = start_poz;
        right_limit = start_poz + dimx;
        new_entry_min = ask_min(j,left_limit,right_limit);
        new_entry_max = ask_max(j,left_limit,right_limit);
        elemente.push_back(new_entry_min);
        elemente.push_back(new_entry_max);
        lowest.insert(new_entry_min);
        highest.insert(new_entry_max);
    }

    for(j=dimy + 1; j< m; ++j)
    {
        int current_delta = *highest.begin() - *lowest.begin();
        if(current_delta == min_delta)
            ++cnt;
        if(current_delta < min_delta)
        {
            min_delta = current_delta;
            cnt = 1;
        }
        int new_entry_min,new_entry_max;
        left_limit = start_poz;
        right_limit = start_poz + dimx;
        new_entry_min = ask_min(j,left_limit,right_limit);
        new_entry_max = ask_max(j,left_limit,right_limit);
        auto del1 = lowest.find(elemente.front());
        lowest.erase(del1);
        elemente.pop_front();
        auto del2 = highest.find(elemente.front());
        highest.erase(del2);
        elemente.pop_front();
        elemente.push_back(new_entry_min);
        elemente.push_back(new_entry_max);
        lowest.insert(new_entry_min);
        highest.insert(new_entry_max);
    }
    int current_delta = *highest.begin() - *lowest.begin();
    if(current_delta == min_delta)
        ++cnt;
    if(current_delta < min_delta)
    {
        min_delta = current_delta;
        cnt = 1;
    }
}
void sweep(int dx, int dy)
{
    int i;
    for(i=0; i + dx - 1 < n ; ++i )
        go_on_row(i,dx-1,dy-1);
}
void solve()
{
    for(int j=0; j<m; j++)
        init_rmq(j);


    while(q--)
    {
        int dx,dy;
        f>>dx>>dy;
        cnt = 0;
        min_delta = INT_MAX;
        sweep(dx,dy);
        if(dx!=dy)
            sweep(dy,dx);
        g<<min_delta<<' '<<cnt<<'\n';
    }
}
void restart()
{

}

int32_t main()
{


    read();
    solve();
    restart();

    return 0;
}