## 题解

### Code

``````#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
const int N = 1005;
using namespace std;

int n, m, a, b, c, d, w[N][N], sum[N][N], val[N][N], l, r, ans;
struct node { int id, val; } q[N];

template < typename T >
{
T x = 0, w = 1; char c = getchar();
while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * w;
}

int getsum(int x1, int y1, int x2, int y2)
{
return sum[x1][y1] - sum[x1][y2] - sum[x2][y1] + sum[x2][y2];
}

int main()
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
w[i][j] = sum[i][j] = read <int> ();
sum[i][j] = sum[i][j] + sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
}
memset(val, 0x3f, sizeof(val));
for(int tmp, i = c; i <= n; i++)
{
l = 1, r = 0;
for(int j = d; j <= n; j++)
{
tmp = getsum(i, j, i - c, j - d);
while(l <= r && q[r].val >= tmp)
r--;
q[++r].val = tmp, q[r].id = j - d + 1;
while(l <= r && q[l].id <= j - b + 2)
l++;
val[i][j] = q[l].val;
}
}
for(int tmp, j = b - 1; j < m; j++)
{
l = 1, r = 0;
for(int i = c; i <= n; i++)
{
if(i - c + a - 1 <= n)
{
tmp = getsum(i - c + a - 1, j + 1, i - c - 1, j - b + 1);
while(l <= r && q[r].val <= tmp)
r--;
q[++r].val = tmp, q[r].id = i - c + a - 1;
}
while(l <= r && q[l].id <= i || q[l].id - a + 1 >= i - c + 1)
l++;
ans = max(ans, q[l].val - val[i][j]);
}
}
printf("%d\n", ans);
return 0;
}``````