Mai intai trebuie sa te autentifici.
Cod sursa(job #2016985)
Utilizator | Data | 31 august 2017 00:09:53 | |
---|---|---|---|
Problema | Struti | Scor | 0 |
Compilator | cpp | Status | done |
Runda | Arhiva de probleme | Marime | 3.06 kb |
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
#include <cassert>
#include <cstring>
#include <climits>
#include <queue>
using namespace std;
typedef long long LL;
#ifdef INFOARENA
#define ProblemName "struti"
#endif
#define MCONCAT(A, B) A B
#ifdef ProblemName
#define InFile MCONCAT(ProblemName, ".in")
#define OuFile MCONCAT(ProblemName, ".out")
#else
#define InFile "fis.in"
#define OuFile "fis.out"
#endif
const int MAXN = 1050, MAXLOG = 12;
int a[2][MAXN][MAXN];
int pre[2][MAXN][MAXN][MAXLOG][MAXLOG];
int N, M, Q;
void rmq_init(int id) {
for (int i = 1; i <= N; ++i)
for (int j = 1; j <= M; ++j)
for (int k = 0; k < MAXLOG; ++k) {
if (k == 0)
pre[id][i][j][k][0] = a[id][i][j];
else {
pre[id][i][j][k][0] = pre[id][i][j][k - 1][0];
int aux = i - (1 << k) + 1;
if (aux >= 1 && pre[id][aux][j][k - 1][0] > pre[id][i][j][k][0])
pre[id][i][j][k][0] = pre[id][aux][j][k - 1][0];
}
for (int l = 1; l < MAXLOG; ++l) {
pre[id][i][j][k][l] = pre[id][i][j][k][l - 1];
int aux = j - (1 << l) + 1;
if (aux >= 1 && pre[id][i][aux][k][l - 1] > pre[id][i][j][k][l])
pre[id][i][j][k][l] = pre[id][i][aux][k][l - 1];
}
}
}
int logtable[MAXN];
void precomputeLogs() {
int cur = 0;
for (int i = 1; i < MAXN; ++i) {
if ((1 << cur) < i)
++cur;
logtable[i] = cur;
}
}
inline int LOG2(int x) {
return logtable[x];
}
#define RELAX() if(cand > best) best = cand;
int rmq(int id, int i1, int j1, int i2, int j2) {
int Li = LOG2(i2 - i1), Lj = LOG2(j2 - j1);
int ii = i1 + (1 << Li) - 1, jj = j1 + (1 << Lj) - 1;
int best = pre[id][ii][jj][Li][Lj];
int cand = pre[id][i2][jj][Li][Lj]; RELAX();
cand = pre[id][ii][j2][Li][Lj]; RELAX();
cand = pre[id][i2][j2][Li][Lj]; RELAX();
return best;
}
void calc1(int dx, int dy, int &best, int &nr) {
for (int i1 = 1, i2 = i1 + dx - 1; i2 <= N; ++i1, ++i2)
for (int j1 = 1, j2 = j1 + dy - 1; j2 <= M; ++j1, ++j2) {
//printf("Considering (%d %d) (%d %d)", i1, j1, i2, j2);
int res0 = rmq(0, i1, j1, i2, j2), res1 = -rmq(1, i1, j1, i2, j2);
int res = res0 - res1;
//printf(" -- result %d : %d - %d\n", res, res0, res1);
if (res < best) {
best = res;
nr = 0;
}
if (res == best)
++nr;
}
}
void input() {
scanf("%d%d%d", &N, &M, &Q);
for (int i = 1; i <= N; ++i)
for (int j = 1; j <= M; ++j) {
if (N <= M) {
scanf("%d", &a[0][i][j]);
a[1][i][j] = -a[0][i][j];
}
else {
scanf("%d", &a[0][j][i]);
a[1][j][i] = -a[0][j][i];
}
}
if (N > M)
swap(N, M);
}
int main() {
assert(freopen(InFile, "r", stdin));
assert(freopen(OuFile, "w", stdout));
precomputeLogs();
input();
rmq_init(0), rmq_init(1);
while (Q--) {
int dx, dy;
scanf("%d%d", &dx, &dy);
int best = INT_MAX, nr = 0;
calc1(dx, dy, best, nr);
if (dx != dy)
calc1(dy, dx, best, nr);
printf("%d %d\n", best, nr);
}
return 0;
}