题意:
思路:
枚举上下边界,将这几行看看成一行,然后就可以双指针跑一遍求最大的合法区间了。最大最小值用线段树或rmq维护即可。复杂度大概
o
(
n
3
m
l
o
g
m
)
o(n ^ 3mlogm)
o(n3mlogm),如果把几行看成一行的过程也用线段树优化一下复杂度就可以是
o
(
n
2
(
l
o
g
n
)
m
(
l
o
g
m
)
)
o(n ^ 2(logn)m(logm))
o(n2(logn)m(logm)).
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 7;
typedef long long ll;
const int mod = 998244353;
int a[101][maxn] , nowa[maxn] , nowi[maxn], n , m , k;
int ma[maxn << 2],mi[maxn << 2];
void build(int l , int r,int rt){
if(l == r){
ma[rt] = nowa[l];
mi[rt] = nowi[l];
return ;
}
int mid = (l + r) / 2;
build(l , mid , rt << 1);
build(mid + 1 , r , rt << 1 | 1);
ma[rt] = max(ma[rt << 1] , ma[rt << 1 | 1]);
mi[rt] = min(mi[rt << 1] , mi[rt << 1 | 1]);
}
int queryma(int L,int R,int l , int r,int rt){
int res = 0;
if(L <= l && R >= r){
return ma[rt];
}
int mid = (l + r) / 2;
if(L <= mid) res = max(res , queryma(L , R , l , mid , rt << 1));
if(R > mid) res = max(res , queryma(L , R , mid + 1 , r , rt << 1 | 1));
return res;
}
int querymi(int L,int R,int l , int r,int rt){
int res = 1e9;
if(L <= l && R >= r){
return mi[rt];
}
int mid = (l + r) / 2;
if(L <= mid) res = min(res , querymi(L , R , l , mid , rt << 1));
if(R > mid) res = min(res , querymi(L , R , mid + 1 , r , rt << 1 | 1));
return res;
}
int cal(int u , int d){
for(int i = 1; i <= m; i ++){
int ma = 0 , mi = 1e9;
for(int j = u; j <= d; j ++){
ma = max(ma , a[j][i]);
mi = min(mi , a[j][i]);
}
// printf ("%d %d\n",ma , mi);
nowa[i] = ma;nowi[i] = mi;
}
build(1 , m , 1);
int r = 1 , ans = 0;
// printf ("%d>>>>>>\n",queryma(1 , 1 , 1 , m ,1));
for(int l = 1; l <= m; l ++){
while(r <= m && queryma(l , r ,1 , m , 1) - querymi(l , r , 1 , m , 1) <= k){
r ++;
}
ans = max(ans , (d - u + 1) * (r - l));
// printf ("%d %d????\n",l , r);
}
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= m; j ++){
scanf("%d",&a[i][j]);
}
}
scanf("%d",&k);
// printf ("%d\n",cal(1 , 3));
int ans = 0;
for(int i = 1; i <= n; i ++){
for(int j = i; j <= n; j ++){
ans = max(ans , cal(i , j));
}
}
printf ("%d\n",ans);
return 0;
}