代码里面已经注释,复杂度可看成O($n^{3}$)
AC代码:
1 #include<bits/stdc++.h> 2 #define numm ch-48 3 #define pd putchar(' ') 4 #define pn putchar(' ') 5 #define pb push_back 6 #define mp make_pair 7 #define fi first 8 #define se second 9 #define fi first 10 #define se second 11 #define fre1 freopen("1.txt","r",stdin) 12 #define fre2 freopen("2.txt","w",stdout) 13 using namespace std; 14 template <typename T> 15 void read(T &res) { 16 bool flag=false;char ch; 17 while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true); 18 for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm); 19 flag&&(res=-res); 20 } 21 template <typename T> 22 void write(T x) { 23 if(x<0) putchar('-'),x=-x; 24 if(x>9) write(x/10); 25 putchar(x%10+'0'); 26 } 27 const int maxn=510; 28 typedef long long ll; 29 typedef long double ld; 30 const ll mod=1e9+7; 31 const int inf=0x3f3f3f3f; 32 int que[maxn][2]; 33 ///2个单调队列,第二维0:维护单调递减的max下标,1:维护单调递增的min下标 34 int a[maxn][maxn]; 35 int mx[maxn],mn[maxn]; 36 ///分别记录每一列的最大值和最小值 37 int main() 38 { 39 int _; 40 read(_); 41 while(_--) { 42 int n,k; 43 read(n),read(k); 44 for(int i=1;i<=n;i++) 45 for(int j=1;j<=n;j++) 46 read(a[i][j]); 47 int ans=1; 48 for(int i=1;i<=n;i++) { ///从i到j这段区间找最大子矩阵 49 for(int j=1;j<=n;j++) { ///记录每列对应的最大值最小值 50 mx[j]=-inf; 51 mn[j]=inf; 52 } 53 for(int j=i;j<=n;j++) { 54 for(int r=1;r<=n;r++) { ///枚举当前行对应的每一列 55 mx[r]=max(mx[r],a[j][r]); 56 mn[r]=min(mn[r],a[j][r]); 57 } 58 int head0=1,tail0=0,head1=1,tail1=0,l=1;///l:从第i到第j行可行的左边界开始 59 for(int r=1;r<=n;r++) { ///枚举第i到第j行可行的右边界,左上角坐标(i,l),右下角坐标(j,r) 60 while(head0<=tail0&&mx[r]>=mx[que[tail0][0]])///单调递减 61 tail0--; 62 while(head1<=tail1&&mn[r]<=mn[que[tail1][1]])///单调递增 63 tail1--; 64 que[++tail0][0]=r; 65 que[++tail1][1]=r; 66 while(l<=r&&mx[que[head0][0]]-mn[que[head1][1]]>k) { 67 l++; 68 if(que[head0][0]<l) head0++; 69 if(que[head1][1]<l) head1++; 70 } 71 ans=max(ans,(j-i+1)*(r-l+1)); 72 } 73 } 74 } 75 write(ans);pn; 76 } 77 return 0; 78 }