Pagini recente » Cod sursa (job #1676117) | Cod sursa (job #2342064) | Cod sursa (job #3142971) | Cod sursa (job #3272215) | Cod sursa (job #2309616)
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <climits>
using namespace std;
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);
}
}
} in("struti.in");
ofstream out("struti.out");
struct Data {
int val;
Data *left = NULL, *right = NULL;
};
class Deque {
int sz = 0;
Data *pos_front = NULL, *pos_back = NULL;
public:
bool size() {
return sz;
}
void push_front(int x) {
Data* node;
node = new Data();
node -> val = x;
sz ++;
if(pos_front != NULL) {
node -> right = pos_front;
pos_front -> left = node;
}
pos_front = node;
if(pos_back == NULL)
pos_back = node;
}
void push_back(int x) {
Data* node;
node = new Data();
node -> val = x;
sz ++;
if(pos_back != NULL) {
node -> left = pos_back;
pos_back -> right = node;
}
pos_back = node;
if(pos_front == NULL)
pos_front = node;
}
void clear() {
delete pos_front;
delete pos_back;
sz = 0;
pos_front = pos_back = NULL;
}
void pop_front() {
if(pos_front == NULL)
return;
sz --;
if(pos_front -> right == NULL) {
delete pos_front;
pos_front = pos_back = NULL;
} else {
pos_front = pos_front -> right;
delete pos_front -> left;
pos_front -> left = NULL;
}
}
void pop_back() {
if(pos_back == NULL)
return;
sz --;
if(pos_back -> left == NULL) {
delete pos_back;
pos_back = pos_front = NULL;
} else {
pos_back = pos_back -> left;
delete pos_back -> right;
pos_back -> right = NULL;
}
}
int back() {
return pos_back -> val;
}
int front() {
return pos_front -> val;
}
};
const int NMAX = 1002;
int v[NMAX][NMAX], n, m;
Deque dmin, dmax;
Deque d;
pair<int, int> solve(int x, int y) {
vector<vector<int>> mn(n + 1, vector<int> (m + 1, 0));
vector<vector<int>> mx(n + 1, vector<int> (m + 1, 0));
for(int i = 1; i <= n; i ++) {
d.clear();
d.push_front(1);
for(int j = 2; j <= m; j ++) {
while(d.size() && v[i][d.back()] < v[i][j])
d.pop_back();
d.push_back(j);
if(j >= x)
mx[i][j] = v[i][d.front()];
if(d.back() - d.front() == x - 1)
d.pop_front();
}
d.clear();
d.push_front(1);
for(int j = 2; j <= m; j ++) {
while(d.size() && v[i][d.back()] > v[i][j])
d.pop_back();
d.push_back(j);
if(j >= x)
mn[i][j] = v[i][d.front()];
if(d.back() - d.front() == x - 1)
d.pop_front();
}
}
int ans = INT_MAX, cnt = 0;
for(int j = x; j <= m; j ++) {
dmin.clear();
dmin.push_front(1);
dmax.clear();
dmax.push_front(1);
for(int i = 2; i <= n; i ++) {
while(dmin.size() && mn[i][j] < mn[dmin.back()][j])
dmin.pop_back();
dmin.push_back(i);
while(dmax.size() && mx[i][j] > mx[dmax.back()][j])
dmax.pop_back();
dmax.push_back(i);
if(i >= y) {
if(mx[dmax.front()][j] - mn[dmin.front()][j] < ans) {
ans = mx[dmax.front()][j] - mn[dmin.front()][j];
cnt = 0;
}
if(mx[dmax.front()][j] - mn[dmin.front()][j] == ans)
cnt ++;
}
if(dmin.back() - dmin.front() == y - 1)
dmin.pop_front();
if(dmax.back() - dmax.front() == y - 1)
dmax.pop_front();
}
}
return {ans, cnt};
}
int main() {
int p;
in >> n >> m >> p;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++)
in >> v[i][j];
while(p --) {
int dx, dy;
in >> dx >> dy;
auto a = solve(dx, dy);
auto b = solve(dy, dx);
if(a.first == b.first && dx != dy)
a.second += b.second;
if(a.first > b.first)
swap(a, b);
out << a.first << " " << a.second << "\n";
}
return 0;
}