先对每一行求一遍滑动窗口,列数变为(列数-k+1)
再对每一列求一遍滑动窗口,行数变为(行数-k+1)
剩下的就是每一个窗口里的最大值啦
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'using namespace std;typedef pair<int, int> PII;
typedef long long ll;
typedef long double ld;const int N = 5010;int n, m, k;
int a[N][N];
int q[N], hh, tt;int main()
{IOScin >> n >> m >> k;for(int i = 1; i <= n; i ++)for(int j = 1; j <= m; j ++)a[i][j] = i * j / __gcd(i, j);for(int i = 1; i <= n; i ++){hh = 0, tt = -1;for(int j = 1; j <= m; j ++){if(hh <= tt && q[hh] < j - k + 1)hh ++;while(hh <= tt && a[i][q[tt]] <= a[i][j])tt --;q[++ tt] = j;if(j >= k)a[i][j - k + 1] = a[i][q[hh]];}}m = m - k + 1;for(int j = 1; j <= m; j ++){hh = 0, tt = -1;for(int i = 1; i <= n; i ++){if(hh <= tt && q[hh] < i - k + 1)hh ++;while(hh <= tt && a[q[tt]][j] <= a[i][j])tt --;q[++ tt] = i;if(i >= k)a[i - k + 1][j] = a[q[hh]][j];}}n = n - k + 1;ll ans = 0;for(int i = 1; i <= n; i ++)for(int j = 1; j <= m; j ++)ans += a[i][j];cout << ans;return 0;
}