
先对每一行求一遍滑动窗口,列数变为(列数-k+1)
再对每一列求一遍滑动窗口,行数变为(行数-k+1)
剩下的就是每一个窗口里的最大值啦
- #include
- #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()
- {
- IOS
- cin >> 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;
- }