Cod sursa(job #3162382)

Utilizator AlexPlesescuAlexPlesescu AlexPlesescu Data 29 octombrie 2023 08:41:06
Problema Struti Scor 100
Compilator cpp-64 Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 8.32 kb
#include <bits/stdc++.h>
#define NMAX 1005
using namespace std;
ifstream fin("struti.in");
ofstream fout("struti.out");

int mn[NMAX][NMAX],mx[NMAX][NMAX],minim,cnt,n,m,t,a[NMAX][NMAX],dx,dy;
int main() {
    fin >> n >> m >> t;
    for(int i=1; i <= n; i++)
        for(int j=1; j <= m; j++)
            fin >> a[i][j];

    while(t--) {
        minim = INT_MAX;
        cnt = 0;
        fin >> dx >> dy;
        deque<pair<int,int>> q,q1;
        /// pt dx dy
        if(dx == dy || dx != dy) {
            for(int j=1; j <= m; j++) {
                q.clear();
                int cnt = 1;
                for(int i=1; i <= dx; i++) {
                    while(!q.empty() && a[i][j] >= a[q.front().first][q.front().second])
                        q.pop_front();
                    q.push_front({i,j});
                }
                mx[1][j] = a[q.back().first][q.back().second];
                for(int i=dx+1; i <= n; i++) {
                    while(!q.empty() && q.back().first < i-dx+1)
                        q.pop_back();
                    while(!q.empty() && a[i][j] >= a[q.front().first][q.front().second])
                        q.pop_front();
                    q.push_front({i,j});
                    mx[++cnt][j] = a[q.back().first][q.back().second];
                }
                for(int i=1; i <= dx-1; i++) {
                    mx[++cnt][j] = a[q.back().first][q.back().second];
                }
            }

            q.clear();

            for(int j=1; j <= m; j++) {
                q.clear();
                int cnt = 1;
                for(int i=1; i <= dx; i++) {
                    while(!q.empty() && a[i][j] <= a[q.front().first][q.front().second])
                        q.pop_front();
                    q.push_front({i,j});
                }
                mn[1][j] = a[q.back().first][q.back().second];
                for(int i=dx+1; i <= n; i++) {
                    while(!q.empty() && q.back().first < i-dx+1)
                        q.pop_back();
                    while(!q.empty() && a[i][j] <= a[q.front().first][q.front().second])
                        q.pop_front();
                    q.push_front({i,j});
                    mn[++cnt][j] = a[q.back().first][q.back().second];
                }
                for(int i=1; i <= dx-1; i++) {
                    mn[++cnt][j] = a[q.back().first][q.back().second];
                }
            }

            q.clear();

            for(int i=1; i <= n-dx+1; i++) {
                q.clear();
                q1.clear();
                for(int j=1; j <= dy; j++) {
                    while(!q.empty() && mx[i][j] >= mx[q.front().first][q.front().second])
                        q.pop_front();
                    q.push_front({i,j});
                    while(!q1.empty() && mn[i][j] <= mn[q1.front().first][q1.front().second])
                        q1.pop_front();
                    q1.push_front({i,j});
                }
                if(mx[q.back().first][q.back().second]-mn[q1.back().first][q1.back().second] < minim)
                    minim = mx[q.back().first][q.back().second]-mn[q1.back().first][q1.back().second], cnt = 1;
                else if(mx[q.back().first][q.back().second]-mn[q1.back().first][q1.back().second] == minim)
                    cnt++;
                for(int j=dy+1; j <= m; j++) {
                    while(!q.empty() && q.back().second < j-dy+1)
                        q.pop_back();
                    while(!q1.empty() && q1.back().second < j-dy+1)
                        q1.pop_back();
                    while(!q.empty() && mx[i][j] >= mx[q.front().first][q.front().second])
                        q.pop_front();
                    q.push_front({i,j});
                    while(!q1.empty() && mn[i][j] <= mn[q1.front().first][q1.front().second])
                        q1.pop_front();
                    q1.push_front({i,j});
                    if(mx[q.back().first][q.back().second]-mn[q1.back().first][q1.back().second] < minim)
                        minim = mx[q.back().first][q.back().second]-mn[q1.back().first][q1.back().second], cnt = 1;
                    else if(mx[q.back().first][q.back().second]-mn[q1.back().first][q1.back().second] == minim)
                        cnt++;

                }
            }
        }
        /// pt dy si dx
        if(dx != dy) {
            q.clear();
            q1.clear();

            for(int j=1; j <= m; j++) {
                q.clear();
                int cnt = 1;
                for(int i=1; i <= dy; i++) {
                    while(!q.empty() && a[i][j] >= a[q.front().first][q.front().second])
                        q.pop_front();
                    q.push_front({i,j});
                }
                mx[1][j] = a[q.back().first][q.back().second];
                for(int i=dy+1; i <= n; i++) {
                    while(!q.empty() && q.back().first < i-dy+1)
                        q.pop_back();
                    while(!q.empty() && a[i][j] >= a[q.front().first][q.front().second])
                        q.pop_front();
                    q.push_front({i,j});
                    mx[++cnt][j] = a[q.back().first][q.back().second];
                }
                for(int i=1; i <= dy-1; i++) {
                    mx[++cnt][j] = a[q.back().first][q.back().second];
                }
            }

            q.clear();

            for(int j=1; j <= m; j++) {
                q.clear();
                int cnt = 1;
                for(int i=1; i <= dy; i++) {
                    while(!q.empty() && a[i][j] <= a[q.front().first][q.front().second])
                        q.pop_front();
                    q.push_front({i,j});
                }
                mn[1][j] = a[q.back().first][q.back().second];
                for(int i=dy+1; i <= n; i++) {
                    while(!q.empty() && q.back().first < i-dy+1)
                        q.pop_back();
                    while(!q.empty() && a[i][j] <= a[q.front().first][q.front().second])
                        q.pop_front();
                    q.push_front({i,j});
                    mn[++cnt][j] = a[q.back().first][q.back().second];
                }
                for(int i=1; i <= dy-1; i++) {
                    mn[++cnt][j] = a[q.back().first][q.back().second];
                }
            }

            q.clear();
            q1.clear();

            for(int i=1; i <= n-dy+1; i++) {
                q.clear();
                q1.clear();
                for(int j=1; j <= dx; j++) {
                    while(!q.empty() && mx[i][j] >= mx[q.front().first][q.front().second])
                        q.pop_front();
                    q.push_front({i,j});
                    while(!q1.empty() && mn[i][j] <= mn[q1.front().first][q1.front().second])
                        q1.pop_front();
                    q1.push_front({i,j});
                }
                if(mx[q.back().first][q.back().second]-mn[q1.back().first][q1.back().second] < minim)
                    minim = mx[q.back().first][q.back().second]-mn[q1.back().first][q1.back().second], cnt = 1;
                else if(mx[q.back().first][q.back().second]-mn[q1.back().first][q1.back().second] == minim)
                    cnt++;
                for(int j=dx+1; j <= m; j++) {
                    while(!q.empty() && q.back().second < j-dx+1)
                        q.pop_back();
                    while(!q1.empty() && q1.back().second < j-dx+1)
                        q1.pop_back();
                    while(!q.empty() && mx[i][j] >= mx[q.front().first][q.front().second])
                        q.pop_front();
                    q.push_front({i,j});
                    while(!q1.empty() && mn[i][j] <= mn[q1.front().first][q1.front().second])
                        q1.pop_front();
                    q1.push_front({i,j});
                    if(mx[q.back().first][q.back().second]-mn[q1.back().first][q1.back().second] < minim)
                        minim = mx[q.back().first][q.back().second]-mn[q1.back().first][q1.back().second], cnt = 1;
                    else if(mx[q.back().first][q.back().second]-mn[q1.back().first][q1.back().second] == minim)
                        cnt++;
                }
            }
        }

        fout << minim << ' ' << cnt << '\n';
    }

    return 0;
}