Cod sursa(job #2724175)

Utilizator AACthAirinei Andrei Cristian AACth Data 16 martie 2021 17:28:58
Problema Struti Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.1 kb
#include <bits/stdc++.h>
using namespace std;
ifstream f("struti.in");
ofstream g("struti.out");

const int Max = 1e3 + 1;
void nos()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
}
int n,m,p;
int a[Max][Max];

void read()
{
    f>>n>>m>>p;
    int i,j;
    for(i=1; i<=n; i++)
        for(j=1; j<=m; j++)
            f>>a[i][j];
}
int delta;
int delta_cnt;
int minMat[Max][Max],maxMat[Max][Max];
struct entry
{
    int indice;
    int val;
};
void precalc(int col,int dx)
{
    int i;
    deque < entry > minx;
    deque < entry > maxx;
    for(i=1; i<=n; i++)
    {

        if(i-dx >= 1)
        {

            minMat[i-dx][col] = minx.front().val;
            maxMat[i-dx][col] = maxx.front().val;
        }
        entry this_entry;
        this_entry.indice = i;
        this_entry.val = a[i][col];
        while(!minx.empty() and minx.back().val > this_entry.val)
            minx.pop_back();
        minx.push_back(this_entry);
        while(!maxx.empty() and maxx.back().val < this_entry.val)
            maxx.pop_back();
        maxx.push_back(this_entry);
        while(!minx.empty() and this_entry.indice - minx.front().indice >= dx)
            minx.pop_front();
        while(!maxx.empty() and this_entry.indice - maxx.front().indice >= dx)
            maxx.pop_front();
    }
    minMat[i-dx][col] = minx.front().val;
    maxMat[i-dx][col] = maxx.front().val;
}
void go_on_row(int poz, int dy)
{
    //iau maxim dy
    int local_delta = INT_MAX;
    deque < entry > minx;
    deque < entry > maxx;
    int i;
    for(i=1; i<=m; i++)
    {
        if(i-dy>=1)
        {
            local_delta = maxx.front().val - minx.front().val;
            if(local_delta == delta)
                delta_cnt ++;
            if(local_delta < delta)
            {
                delta = local_delta;
                delta_cnt = 1;
            }
        }
        while(!minx.empty() and minx.back().val > minMat[poz][i])
            minx.pop_back();
        minx.push_back({i,minMat[poz][i]});
        while(!maxx.empty() and maxx.back().val < maxMat[poz][i])
            maxx.pop_back();
        maxx.push_back({i,maxMat[poz][i]});
        while(!minx.empty() and i - minx.front().indice >= dy)
            minx.pop_front();
        while(!maxx.empty() and i - maxx.front().indice >= dy)
            maxx.pop_front();
    }
    local_delta = maxx.front().val - minx.front().val;
    if(local_delta == delta)
        delta_cnt ++;
    if(local_delta < delta)
    {
        delta = local_delta;
        delta_cnt = 1;
    }
}
void fix(int dx, int dy)
{
    //prentru fiecare coloana precalculez
    int i,j;
    for(j=1; j<=m; j++)
        precalc(j,dx);
    for(i=1; i + dx - 1<=n; i++ )
        go_on_row(i,dy);
}
void solve()
{
    while(p--)
    {
        delta = INT_MAX;
        delta_cnt = 0;
        int dx,dy;
        f>>dx>>dy;
        fix(dx,dy);
        if(dx!=dy)
            fix(dy,dx);
        g<<delta<<' '<<delta_cnt<<'\n';
    }

}
void restart()
{

}

int32_t main()
{
    read();
    solve();
    return 0;
}