Title Link
Title Solution
It is obvious that the algorithm of strict \ (O(n^3) \) is needed.
First, consider a method that can't be overstepped. Enumerate \ ((x,y) \) in the lower right corner, and then divide the rectangular area into two parts. Enumerate one side, and the complexity is \ (O(n^3 \log n^2) \).
Consider another approach, which is to enumerate the lower right corner \ ((x,y)), and then enumerate the length of one side. Obviously, now you only need to know where the farthest left side can extend. This thing is obviously monotonous. Take a ruler and set a monotonous queue to judge.
Pay attention to the details.
#include <bits/stdc++.h> using namespace std; namespace io { char buf[1<<21], *p1 = buf, *p2 = buf; inline char gc() { if(p1 != p2) return *p1++; p1 = buf; p2 = p1 + fread(buf, 1, 1 << 21, stdin); return p1 == p2 ? EOF : *p1++; } #define G gc #ifndef ONLINE_JUDGE #undef G #define G getchar #endif template<class I> inline void read(I &x) { x = 0; I f = 1; char c = G(); while(c < '0' || c > '9') {if(c == '-') f = -1; c = G(); } while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = G(); } x *= f; } template<class I> inline void write(I x) { if(x == 0) {putchar('0'); return;} I tmp = x > 0 ? x : -x; if(x < 0) putchar('-'); int cnt = 0; while(tmp > 0) { buf[cnt++] = tmp % 10 + '0'; tmp /= 10; } while(cnt > 0) putchar(buf[--cnt]); } #define in(x) read(x) #define outn(x) write(x), putchar('\n') #define out(x) write(x), putchar(' ') } using namespace io; #define ll long long const int N = 510; struct Node { int x, y, v; }; int T, n, m; int a[N][N], mx[N], mn[N]; int qmin[N], qmax[N]; int main() { read(T); while(T--) { int ans = 0; read(n); read(m); for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) read(a[i][j]); for(int l = 1; l <= n; ++l) { for(int i = 1; i <= n; ++i) mn[i] = 1e9, mx[i] = 0; for(int r = l; r <= n; ++r) { for(int i = 1; i <= n; ++i) { mn[i] = min(mn[i], a[r][i]); mx[i] = max(mx[i], a[r][i]); } int cur = 1, l0 = 1, l1 = 1, r0 = 0, r1 = 0; for(int i = 1; i <= n; ++i) { while(l0 <= r0 && mn[qmin[r0]] > mn[i]) --r0; while(l1 <= r1 && mx[qmax[r1]] < mx[i]) --r1; qmin[++r0] = i; qmax[++r1] = i; while(l0 <= r0 && l1 <= r1 && cur <= i && mx[qmax[l1]] - mn[qmin[l0]] > m) { ++cur; while(l0 <= r0 && qmin[l0] < cur) ++l0; while(l1 <= r1 && qmax[l1] < cur) ++l1; } if(mx[qmax[l1]] - mn[qmin[l0]] <= m) ans = max(ans, (r - l + 1) * (i - cur + 1)); } } } outn(ans); } }