Pagini recente » Cod sursa (job #1412820) | Cod sursa (job #1021846) | Cod sursa (job #984370) | Clasament 13 | Cod sursa (job #1696307)
#include <fstream>
#include <cstring>
#define Pe pair <int, int>
#define mp make_pair
#define fi first
#define se second
using namespace std;
const int MaxN = 1005, MaxAltit = 8005, INF = 0x3f3f3f3f, MaxDqSz = 100005;
int mat[MaxN][MaxN], MinMat[MaxN][MaxN], MaxMat[MaxN][MaxN];
int n, m, p;
class Deque {
int l, r, v[MaxDqSz];
public:
Deque() {
memset(v, 0, sizeof v);
l = 1;
r = 0;
}
inline void push_back(const int &x) {
++r;
v[r] = x;
}
inline void pop_back() {
--r;
}
inline void pop_front() {
++l;
}
inline int front() {
return v[l];
}
inline int back() {
return v[r];
}
inline int size() {
return r - l + 1;
}
};
Deque MaxDq, MinDq;
class InputReader {
public:
InputReader() {}
InputReader(const char *file_name) {
input_file = fopen(file_name, "r");
cursor = 0;
fread(buffer, SIZE, 1, input_file);
}
inline InputReader &operator >>(int &n) {
while (buffer[cursor] < '0' || buffer[cursor] > '9') {
advance();
}
n = 0;
while ('0' <= buffer[cursor] && buffer[cursor] <= '9') {
n = n * 10 + buffer[cursor] - '0';
advance();
}
return *this;
}
private:
FILE *input_file;
static const int SIZE = 1 << 17;
int cursor;
char buffer[SIZE];
inline void advance() {
++ cursor;
if (cursor == SIZE) {
cursor = 0;
fread(buffer, SIZE, 1, input_file);
}
}
};
InputReader cin("struti.in");
ofstream cout("struti.out");
void PreCalc(int LineNr) {
memset(MinMat, 0, sizeof MinMat);
memset(MaxMat, 0, sizeof MaxMat);
for (int j = 1; j <= m; ++j) {
MaxDq = Deque();
MinDq = Deque();
for (int i = 1; i <= n; ++i) {
while (MinDq.size() > 0 and MinDq.front() <= i - LineNr) {
MinDq.pop_front();
}
while (MinDq.size() > 0 and mat[i][j] < mat[MinDq.back()][j]) {
MinDq.pop_back();
}
MinDq.push_back(i);
MinMat[i][j] = mat[MinDq.front()][j];
while (MaxDq.size() > 0 and MaxDq.front() <= i - LineNr) {
MaxDq.pop_front();
}
while (MaxDq.size() > 0 and mat[i][j] > mat[MaxDq.back()][j]) {
MaxDq.pop_back();
}
MaxDq.push_back(i);
MaxMat[i][j] = mat[MaxDq.front()][j];
}
}
}
Pe solve(int LineNr, int ColumnNr) {
PreCalc(LineNr);
int ans = INF;
int cnt = 0;
for (int i = LineNr; i <= n; ++i) {
MaxDq = Deque();
MinDq = Deque();
for (int j = 1; j <= m; ++j) {
while (MinDq.size() > 0 and MinDq.front() <= j - ColumnNr) {
MinDq.pop_front();
}
while (MinDq.size() > 0 and MinMat[i][j] < MinMat[i][MinDq.back()]) {
MinDq.pop_back();
}
MinDq.push_back(j);
while (MaxDq.size() > 0 and MaxDq.front() <= j - ColumnNr) {
MaxDq.pop_front();
}
while (MaxDq.size() > 0 and MaxMat[i][j] > MaxMat[i][MaxDq.back()]) {
MaxDq.pop_back();
}
MaxDq.push_back(j);
if (j >= ColumnNr) {
int candidate = MaxMat[i][MaxDq.front()] - MinMat[i][MinDq.front()];
if (candidate == ans) {
++cnt;
}
else if (candidate < ans) {
ans = candidate;
cnt = 1;
}
}
}
}
return mp(ans, cnt);
}
int main() {
cin >> n >> m >> p;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
cin >> mat[i][j];
}
}
for (int i = 1; i <= p; ++i) {
int x, y;
cin >> x >> y;
Pe Ans;
Pe Ans1 = solve(x, y);
Pe Ans2;
if (x != y) {
Ans2 = solve(y, x);
}
else {
Ans2 = mp(INF, INF);
}
if (Ans1.fi == Ans2.fi) {
Ans = Ans1;
Ans.se += Ans2.se;
}
else {
Ans = min(Ans1, Ans2);
}
cout << Ans.fi << ' ' << Ans.se << '\n';
}
return 0;
}