Rectangular $ C \ times D $ rectangular $ A \ times B $ among (no common edge), the contribution is defined as a rectangle $ A \ times B $ rectangular $ C \ times D $ elements and the difference between the maximum contribution to seek .
Consider monotonous queue. Twice dp, to find the $ (i, j) $ is the smallest of the small rectangular elements and large rectangle included in the lower right corner.
// luogu-judger-enable-o2 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define mid (l+r)/2 #define N 100005 #define log 40 #define lowbit(x) x&-x #define mod 998244353 using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int sum1[1005][1005],sum2[1005][1005],sum[1005][1005]; int num[1005][1005]; int q1[1005][1005],q2[1005][1005]; int q[10005]; int l,r; int n,m,a,b,c,d; int main() { scanf("%d%d",&n,&m); scanf("%d%d%d%d",&a,&b,&c,&d); int i,j,k; for(i=1;i<=n;i++) for(j=1;j<=m;j++) scanf("%d",&num[i][j]); for(i=1;i<=n;i++) for(j=1;j<=m;j++) sum[i][j]=sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1]+num[i][j]; for(i=a;i<=n;i++) for(j=b;j<=m;j++) sum1[i][j]=sum[i][j]-sum[i][j-b]+sum[i-a][j-b]-sum[i-a][j]; for(i=c+1;i<n;i++) for(j=d+1;j<m;j++) sum2[i][j]=sum[i][j]-sum[i][j-d]+sum[i-c][j-d]-sum[i-c][j]; for(i=c+1;i<n;i++) { l=1; r=0; for(j=d+1;j<m;j++) { while(l<=r&&q[l]<j-b+2+d) l++; while(l<=r&&sum2[i][q[r]]>=sum2[i][j]) r--; q[++r]=j; if(j>=b-1) q1[i][j+1]=sum2[i][q[l]]; } } for(j=b;j<=m;j++) { l=1; r=0; for(i=c+1;i<n;i++) { while(l<=r&&q[l]<i-a+2+c) l++; while(l<=r&&q1[q[r]][j]>=q1[i][j]) r--; q[++r]=i; if(i>=a-1) q2[i+1][j]=q1[q[l]][j]; } } int ans=0; for(i=a;i<=n;i++) for(j=b;j<=m;j++) ans=max(ans,sum1[i][j]-q2[i][j]); cout<<ans; return 0; }