Pagini recente » Cod sursa (job #243219) | Cod sursa (job #1715689) | Cod sursa (job #2506490) | Cod sursa (job #1484134) | Cod sursa (job #2133524)
//P * N^2 * log2(N) ar trebui sa intre
#pragma GCC optimize("03")
#include <bits/stdc++.h>
#define N 1003
#define L (pos << 1)
#define R (L | 1)
#define INF 8001
using namespace std;
int n, m, x, y, q, bst, cnt, a[N][N], freqmin[8 * N], freqmax[8 * N];
int blocks_min[N][N], blocks_max[N][N];
#define dim 100000
char buff[dim];
int p = 0;
void read(int &nr){
nr = 0;
while(buff[p] < '0' || buff[p] > '9')
if(++p == dim)
fread(buff, 1, dim, stdin), p = 0;
while(buff[p] >= '0' && buff[p] <= '9'){
nr = 10 * nr + buff[p] - '0';
if(++p == dim)
fread(buff, 1, dim, stdin), p = 0;
}
}
void build_blocks(int sz){
memset(blocks_max, 0, sizeof blocks_max);
memset(blocks_min, 0, sizeof blocks_min);
deque <int> dqmax, dqmin;
for(int j = 1; j <= m; j++){
dqmax.clear();
dqmin.clear();
for(int i = 1; i <= sz; i++){
while(!dqmax.empty() && a[dqmax.back()][j] <= a[i][j])
dqmax.pop_back();
dqmax.push_back(i);
while(!dqmin.empty() && a[dqmin.back()][j] >= a[i][j])
dqmin.pop_back();
dqmin.push_back(i);
}
blocks_max[1][j] = a[dqmax.front()][j];
blocks_min[1][j] = a[dqmin.front()][j];
for(int i = sz + 1; i <= n; i++){
while(!dqmax.empty() && a[dqmax.back()][j] <= a[i][j])
dqmax.pop_back();
dqmax.push_back(i);
while(!dqmax.empty() && dqmax.front() < i - sz + 1)
dqmax.pop_front();
while(!dqmin.empty() && a[dqmin.back()][j] >= a[i][j])
dqmin.pop_back();
dqmin.push_back(i);
while(!dqmin.empty() && dqmin.front() < i - sz + 1)
dqmin.pop_front();
blocks_max[i - sz + 1][j] = a[dqmax.front()][j];
blocks_min[i - sz + 1][j] = a[dqmin.front()][j];
}
}
}
void solve(int dx, int dy){
build_blocks(dx);
deque <int> dqmax, dqmin;
int mx, mn;
for(int i = 1; i + dx - 1 <= n; i++){
dqmax.clear();
dqmin.clear();
for(int j = 1; j <= dy; j++){
while(!dqmax.empty() && blocks_max[i][dqmax.back()] <= blocks_max[i][j])
dqmax.pop_back();
dqmax.push_back(j);
while(!dqmin.empty() && blocks_min[i][dqmin.back()] >= blocks_min[i][j])
dqmin.pop_back();
dqmin.push_back(j);
}
mx = blocks_max[i][dqmax.front()];
mn = blocks_min[i][dqmin.front()];
if(mx - mn == bst)
cnt++;
else if(mx - mn < bst){
bst = mx - mn;
cnt = 1;
}
for(int j = dy + 1; j <= m; j++){
while(!dqmax.empty() && blocks_max[i][dqmax.back()] <= blocks_max[i][j])
dqmax.pop_back();
dqmax.push_back(j);
while(!dqmax.empty() && dqmax.front() < j - dy + 1)
dqmax.pop_front();
while(!dqmin.empty() && blocks_min[i][dqmin.back()] >= blocks_min[i][j])
dqmin.pop_back();
dqmin.push_back(j);
while(!dqmin.empty() && dqmin.front() < j - dy + 1)
dqmin.pop_front();
mx = blocks_max[i][dqmax.front()];
mn = blocks_min[i][dqmin.front()];
if(mx - mn == bst)
cnt++;
else if(mx - mn < bst){
bst = mx - mn;
cnt = 1;
}
}
}
}
int main(){
freopen("struti.in", "r", stdin);
freopen("struti.out", "w", stdout);
read(n); read(m); read(q);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
read(a[i][j]);
while(q--){
read(x); read(y);
bst = INF; cnt = 0;
solve(x, y);
if(x != y)
solve(y, x);
cout << bst << ' ' << cnt << '\n';
}
return 0;
}