题目

我是一个小沙比,爆零本领强~

T1

看起来是一道很捞的、做过无数遍的区间最大值。

直接$O(n^3)$做一做就完了……

具体做法就是预处理每行的前缀和,然后二重循环枚举一个固定的列区间,再用单调队列的思想,从第一行不停向下扩展行区间,如果矩阵内总和$\gt k$ 了就从行区间顶部不停删行,删到矩阵内总和$\le k$ 为止。每当矩阵总和满足限制时,更新矩阵面积最大值即可。

当然如果你很想大战$T1$的话,可以写个$O(n^2*log(n^2))$的主席树?

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<algorithm>
 7 #define N 501
 8 using namespace std;
 9 inline int read(){
10     int x=0; bool f=1; char c=getchar();
11     for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
12     for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0');
13     if(f) return x;
14     return 0-x;
15 }
16 int n,m,e[N][N],sum[N][N],x,ans;
17 int main(){
18     n=read()+1,m=read();
19     int i,j,k,go;
20     for(i=1;i^n;++i)
21         for(j=1;j^n;++j)
22             sum[i][j]=sum[i][j-1]+read();
23     for(i=1;i^n;++i){
24         for(j=i;j^n;++j){
25             x=0, go=1;
26             for(k=1;k^n;++k){
27                 x+=sum[k][j]-sum[k][i-1];
28                 while(x>m) x-=sum[go][j]-sum[go][i-1], ++go;
29                 ans=max(ans,(j-i+1)*(k-go+1));
30             }
31         }
32     }
33     printf("%d\n",ans);        
34     return 0;
35 }
View Code

相关文章: