【子矩阵——优先队列】
题目
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e3 + 10;
const int mod = 998244353;
int g[N][N], ymax[N][N], ymin[N][N];
deque<int> qxmax[N], qxmin[N], qymax[N], qymin[N];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int n, m, a, b;
cin >> n >> m >> a >> b;
// 初始化矩阵
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> g[i][j];
}
}
// 垂直方向的滑动窗口(按列计算)
for (int j = 1; j <= m; j++) {
for (int i = 1; i <= n; i++) {
// 最大值队列
while (!qymax[j].empty() && g[qymax[j].back()][j] <= g[i][j]) qymax[j].pop_back();
qymax[j].push_back(i);
// 最小值队列
while (!qymin[j].empty() && g[qymin[j].back()][j] >= g[i][j]) qymin[j].pop_back();
qymin[j].push_back(i);
// 窗口内数据有效
if (i >= a) {
if (i - qymax[j].front() + 1 > a) qymax[j].pop_front();
if (i - qymin[j].front() + 1 > a) qymin[j].pop_front();
ymax[i][j] = g[qymax[j].front()][j]; // 存储具体值
ymin[i][j] = g[qymin[j].front()][j]; // 存储具体值
}
}
}
// 水平方向的滑动窗口(按行计算)
ll res = 0;
for (int i = a; i <= n; i++) {
for (int j = 1; j <= m; j++) {
// 最大值队列
while (!qxmax[i].empty() && ymax[i][qxmax[i].back()] <= ymax[i][j]) qxmax[i].pop_back();
qxmax[i].push_back(j);
// 最小值队列
while (!qxmin[i].empty() && ymin[i][qxmin[i].back()] >= ymin[i][j]) qxmin[i].pop_back();
qxmin[i].push_back(j);
// 窗口内数据有效
if (j >= b) {
if (j - qxmax[i].front() + 1 > b) qxmax[i].pop_front();
if (j - qxmin[i].front() + 1 > b) qxmin[i].pop_front();
res = (res + (ll)ymax[i][qxmax[i].front()] * ymin[i][qxmin[i].front()]) % mod;
}
}
}
// 输出结果
cout << res << endl;
return 0;
}
原文地址:https://blog.csdn.net/m0_73669127/article/details/145309664
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!