Pagini recente » Cod sursa (job #2592540) | Cod sursa (job #459212) | Cod sursa (job #1255788) | Cod sursa (job #2180338) | Cod sursa (job #2208632)
#include <fstream>
#include <deque>
#include <climits>
using namespace std;
ifstream fin("struti.in");
ofstream fout("struti.out");
typedef unsigned int Natural;
const Natural maxSZ = 1005, Inf = UINT_MAX;
class InParser {
private:
ifstream File;
static const Natural buffSZ = (1 << 15);
char buff[buffSZ];
Natural buffPos;
void _advance() {
if (++buffPos == buffSZ) {
buffPos = 0;
File.read(buff, buffSZ);
}
}
public:
InParser& operator >>(Natural &no) {
while (!isdigit(buff[buffPos]))
_advance();
no = 0;
while (isdigit(buff[buffPos])) {
no = no * 10 + buff[buffPos] - '0';
_advance();
}
return *this;
}
};
Natural rows, cols, Q;
Natural Grid[maxSZ][maxSZ], maxGrid[maxSZ][maxSZ], minGrid[maxSZ][maxSZ];
deque <Natural> minDeque, maxDeque;
Natural minDiff, cnt;
void readData() {
fin >> rows >> cols >> Q;
for (Natural row = 1; row <= rows; ++row)
for (Natural col = 1; col <= cols; ++col)
fin >> Grid[row][col];
}
inline void buildMinMax_Grid(const Natural &rectRows, const Natural &rectCols) {
for (Natural row = 1; row <= rows; ++row) {
for (Natural col = 1; col < rectCols; ++col) {
while (!minDeque.empty() && Grid[row][minDeque.back()] > Grid[row][col])
minDeque.pop_back();
minDeque.push_back(col);
while (!maxDeque.empty() && Grid[row][maxDeque.back()] < Grid[row][col])
maxDeque.pop_back();
maxDeque.push_back(col);
}
for (Natural col = rectCols; col <= cols; ++col) {
while (!minDeque.empty() && Grid[row][minDeque.back()] > Grid[row][col])
minDeque.pop_back();
minDeque.push_back(col);
while (!maxDeque.empty() && Grid[row][maxDeque.back()] < Grid[row][col])
maxDeque.pop_back();
maxDeque.push_back(col);
maxGrid[row][col - rectCols + 1] = Grid[row][maxDeque.front()];
minGrid[row][col - rectCols + 1] = Grid[row][minDeque.front()];
while (minDeque.front() < col - rectCols + 2)
minDeque.pop_front();
while (maxDeque.front() < col - rectCols + 2)
maxDeque.pop_front();
}
maxDeque.clear(); minDeque.clear();
}
}
inline void contorRects(const Natural &rectRows, const Natural &rectCols) {
for (Natural col = 1; col <= cols - rectCols + 1; ++col) {
for (Natural row = 1; row < rectRows; ++row) {
while (!minDeque.empty() && minGrid[minDeque.back()][col] > minGrid[row][col])
minDeque.pop_back();
minDeque.push_back(row);
while (!maxDeque.empty() && maxGrid[maxDeque.back()][col] < maxGrid[row][col])
maxDeque.pop_back();
maxDeque.push_back(row);
}
for (Natural row = rectRows; row <= rows; ++row) {
while (!minDeque.empty() && minGrid[minDeque.back()][col] > minGrid[row][col])
minDeque.pop_back();
minDeque.push_back(row);
while (!maxDeque.empty() && maxGrid[maxDeque.back()][col] < maxGrid[row][col])
maxDeque.pop_back();
maxDeque.push_back(row);
if (maxGrid[maxDeque.front()][col] - minGrid[minDeque.front()][col] < minDiff) {
minDiff = maxGrid[maxDeque.front()][col] - minGrid[minDeque.front()][col];
cnt = 1;
}
else if (maxGrid[maxDeque.front()][col] - minGrid[minDeque.front()][col] == minDiff)
++cnt;
while (minDeque.front() < row - rectRows + 2)
minDeque.pop_front();
while (maxDeque.front() < row - rectRows + 2)
maxDeque.pop_front();
}
maxDeque.clear(); minDeque.clear();
}
}
inline pair <Natural, Natural> getRects(const Natural &rectRows, const Natural &rectCols) {
minDiff = Inf, cnt = 0;
buildMinMax_Grid(rectRows, rectCols);
contorRects(rectRows, rectCols);
buildMinMax_Grid(rectCols, rectRows);
contorRects(rectCols, rectRows);
return {minDiff, cnt};
}
int main() {
readData();
while (Q--) {
Natural rectRows, rectCols;
fin >> rectRows >> rectCols;
pair <Natural, Natural> Rects = getRects(rectRows, rectCols);
if (rectRows == rectCols)
Rects.second >>= 1;
fout << Rects.first << ' ' << Rects.second << '\n';
}
}