这题应该有更简单的方法做,本人太懒,直接暴力线段树+优先队列了,刚好卡时间过
#include#include #include #include #include using namespace std; typedef long long LL; typedef pair pii; const int mod = 1e9 + 7 , INF = 0x3f3f3f3f , N = 1e5 + 10; int g[100][N]; int n,m; int limit; struct edge1 { int v; int id; bool operator < (const edge1 & w)const { if (v != w.v) return v < w.v; return id > w.id; } }; struct edge2 { int v; int id; bool operator < (const edge2 & w)const { if (v != w.v) return v > w.v; return id > w.id; } }; struct Node { int l,r; int minv; int maxv; }tr[N * 4]; void push_up(int x) { tr[x].minv = min(tr[x << 1].minv,tr[x << 1 | 1].minv); tr[x].maxv = max(tr[x << 1].maxv,tr[x << 1 | 1].maxv); } void build(int x,int l,int r) { tr[x] = {l,r}; if (l == r) { int w = g[(r - 1) % n + 1][(r - 1) / n + 1]; tr[x] = {l,r,w,w}; return; } int mid = l + r >> 1; build(x << 1,l,mid); build(x << 1 | 1,mid + 1,r); push_up(x); } int queryMin(int x,int l,int r) { if (tr[x].l >= l && tr[x].r <= r) return tr[x].minv; int mid = tr[x].l + tr[x].r >> 1; int minv = INF; if (l <= mid) minv = queryMin(x << 1,l,r); if (r > mid) minv = min(minv,queryMin(x << 1 | 1,l,r)); return minv; } int queryMax(int x,int l,int r) { if (tr[x].l >= l && tr[x].r <= r) return tr[x].maxv; int mid = tr[x].l + tr[x].r >> 1; int maxv = -1; if (l <= mid) maxv = queryMax(x << 1,l,r); if (r > mid) maxv = max(maxv,queryMax(x << 1 | 1,l,r)); return maxv; } void init() { scanf("%d%d",&n,&m); for (int i = 1 ; i <= n ; i ++) for (int j = 1 ; j <= m ; j ++) scanf("%d",&g[i][j]); scanf("%d",&limit); build(1,1,n * (m + 1)); } int getMin(int i1,int j1,int i2,int j2) { int a = i1 + n * (j1 - 1); int b = i2 + n * (j2 - 1); return queryMin(1,a,b); } int getMax(int i1,int j1,int i2,int j2) { int a = i1 + n * (j1 - 1); int b = i2 + n * (j2 - 1); return queryMax(1,a,b); } int main() { init(); int res = 0; for (int i1 = 1 ; i1 <= n ; i1 ++) for (int i2 = i1 ; i2 <= n ; i2 ++) { priority_queue q1; priority_queue q2; for (int l = 1,r = 1; r <= m ; r ++) { int maxv = getMax(i1,r,i2,r); int minv = getMin(i1,r,i2,r); if (maxv - minv > limit) { while (q1.size()) q1.pop(); while (q2.size()) q2.pop(); l = r + 1; continue; } while (q1.size() && q1.top().v <= maxv) q1.pop(); q1.push({maxv,r}); while (q2.size() && q2.top().v >= minv) q2.pop(); q2.push({minv,r}); while (q1.top().v - q2.top().v > limit) { l ++; while (q1.size() && q1.top().id < l) q1.pop(); while (q2.size() && q2.top().id < l) q2.pop(); } res = max(res,(i2 - i1 + 1) * (r - l + 1)); } } printf("%d",res); return 0; }



