Pagini recente » Borderou de evaluare (job #1146016) | Borderou de evaluare (job #985550) | Borderou de evaluare (job #444250) | Borderou de evaluare (job #2612105) | Cod sursa (job #1967774)
#include <bits/stdc++.h>
using namespace std;
class InParser {
private:
FILE *fin;
char *buff;
int sp;
char read_ch() {
++sp;
if (sp == 4096) {
sp = 0;
fread(buff, 1, 4096, fin);
}
return buff[sp];
}
public:
InParser(const char* nume) {
fin = fopen(nume, "r");
buff = new char[4096]();
sp = 4095;
}
InParser& operator >> (int &n) {
char c;
while (!isdigit(c = read_ch()) && c != '-');
int sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
InParser& operator >> (long long &n) {
char c;
n = 0;
while (!isdigit(c = read_ch()) && c != '-');
long long sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
};
#define INF 1000000000
#define MAXN 1050
int N, M, P;
int A[MAXN][MAXN];
int D[MAXN], front, back;
int vmin[MAXN][MAXN], vmax[MAXN][MAXN];
int vmin2D[MAXN][MAXN];
pair<int, int> solve(int dx, int dy) {
for (int i = 0; i < N; i++) {
front = 1;
back = 0;
for (int j = 0; j < M; j++) {
while (front <= back && A[i][j] <= A[i][ D[back] ]) {
back--;
}
D[++back] = j;
if (D[front] == j - dy) {
front++;
}
vmin[i][j] = A[i][ D[front] ];
}
}
for (int j = 0; j < M; j++) {
front = 1;
back = 0;
for (int i = 0; i < N; i++) {
while (front <= back && vmin[i][j] <= vmin[ D[back] ][j]) {
back--;
}
D[++back] = i;
if (D[front] == i - dx) {
front++;
}
vmin2D[i][j] = vmin[ D[front] ][j];
}
}
for (int i = 0; i < N; i++) {
front = 1;
back = 0;
for (int j = 0; j < M; j++) {
while (front <= back && A[i][j] >= A[i][ D[back] ]) {
back--;
}
D[++back] = j;
if (D[front] == j - dy) {
front++;
}
vmax[i][j] = A[i][ D[front] ];
}
}
int dmin = INF;
int cnt = 0;
for (int j = 0; j < M; j++) {
front = 1;
back = 0;
for (int i = 0; i < N; i++) {
while (front <= back && vmax[i][j] >= vmax[ D[back] ][j]) {
back--;
}
D[++back] = i;
if (D[front] == i - dx) {
front++;
}
int vmax2D = vmax[ D[front] ][j];
if (i >= dx - 1 && j >= dy - 1) {
int diff = vmax2D - vmin2D[i][j];
if (diff < dmin) {
dmin = diff;
cnt = 1;
} else if (diff == dmin) {
cnt++;
}
}
}
}
return { dmin, cnt };
}
int main() {
// assert(freopen("struti.in", "r", stdin));
InParser fin("struti.in");
assert(freopen("struti.out", "w", stdout));
cin.sync_with_stdio(false);
// cin >> N >> M >> P;
fin >> N >> M >> P;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
// cin >> A[i][j];
fin >> A[i][j];
}
}
int dx, dy;
while (P-- > 0) {
// cin >> dx >> dy;
fin >> dx >> dy;
auto res = solve(dx, dy);
if (dx != dy) {
auto res2 = solve(dy, dx);
if (res2.first < res.first) {
res = res2;
} else if (res2.first == res.first) {
res.second += res2.second;
}
}
cout << res.first << ' ' << res.second << '\n';
}
return 0;
}