蓝桥杯刷题-13-子矩阵-二维滑动窗口 ಥ_ಥ

给定一个 n × m (n 行 m 列)的矩阵。

设一个矩阵的价值为其所有数中的最大值和最小值的乘积。求给定矩阵的所有大小为 a × b (a 行 b 列)的子矩阵的价值的和。

答案可能很大,你只需要输出答案对 998244353 取模后的结果。

cpp 复制代码
//四层for循环
for(){//行n
	for(){//列m
		for(){//a
			for(){//b
			}
		}
	}

}


cpp 复制代码
//二维单调队列
#include<bits/stdc++.h>
#define endl '\n'
#define deb(x) cout << #x << " = " << x << '\n';
#define INF 0x3f3f3f3f
#define int long long
using namespace std;
const int mod =  998244353;
const int N = 1e3 + 10;
int g[N][N];
int q[N];
int line_max[N][N], line_min[N][N];
int maxv[N][N], minv[N][N];
int a, b, n, m;

void solve()
{
	cin >> n >> m >> a >> b;
	for(int i = 0; i < n; i ++)
		for(int j = 0; j < m; j ++)
			cin >> g[i][j];

	//求出每一行的滑动窗口
	for(int i = 0; i < n; i ++){
		int h = 0, t = -1;
		for(int j = 0; j < m; j ++){

			if(h <= t and q[h] < j - b + 1){
				h ++;
			}
			while(h <= t and g[i][q[t]] <= g[i][j])
				t--;

			q[++t] = j;
			if(j - b + 1 >= 0){
				line_max[i][j - b + 1] = g[i][q[h]];
			}
		}
	}
	
	//对每一行的滑动窗口求一遍滑动窗口
	for(int j = 0; j < m; j ++){
		int h = 0, t = -1;
		for(int i = 0; i < n; i ++){
			if(h <= t and q[h] < i - a + 1){
				h ++;
			}
			while(h <= t and line_max[q[t]][j] <= line_max[i][j])
				t --;
			
			q[++t] = i;
			if(i - a + 1 >= 0)
				maxv[i - a + 1][j] = line_max[q[h]][j];
		}
	}



	//求最小值
	//先针对每一行,求出每一行的滑动窗口。
	for(int i = 0; i < n; i ++){
		int h = 0, t = -1;
		for(int j = 0; j < m; j ++){
			if(h <= t and q[h] < j - b + 1){
				h ++;
			}
			while(h <= t and g[i][q[t]] >= g[i][j])
				t --;
			q[++ t] = j;
			if(j - b + 1 >= 0)
				line_min[i][j - b + 1] = g[i][q[h]]; 
		}
	}


	//针对每一列的滑动黑窗口,求滑动窗口。
	for(int j = 0; j < m; j ++){
		int h = 0, t = -1;
		for(int i = 0; i < n; i ++){
			if(h <= t and q[h] < i - a + 1){
				h ++;
			}
			while(h <= t and line_min[q[t]][j] >= line_min[i][j])
				t --;
			q[++ t] = i;
			if(i - a + 1 >= 0)
				minv[i - a + 1][j] = line_min[q[h]][j];
		}
	}

	int ans = 0;
	for(int i = 0; i < n; i ++){
		for(int j = 0; j < m; j ++){
			ans = (ans + maxv[i][j] * minv[i][j] % mod) % mod;
		}
	}
	cout << ans << endl;

}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	t = 1;
	//cin >> t;
	while(t--)
	solve();
}
相关推荐
牵牛老人4 小时前
OpenCV学习探秘之二 :数字图像的矩阵原理,OpenCV图像类与常用函数接口说明,及其常见操作核心技术详解
opencv·学习·矩阵
lqjun08278 小时前
相机内外参矩阵:从3D世界坐标到2D像素坐标变换
数码相机·3d·矩阵
恣艺9 小时前
LeetCode 1074:元素和为目标值的子矩阵数量
算法·leetcode·矩阵
Alfred king9 小时前
面试150 搜索二维矩阵
线性代数·矩阵·二分查找·数组
Alfred king1 天前
面试150 建立四叉树
矩阵··数组·分治
石去皿1 天前
QKV 为什么是三个矩阵?注意力为何要除以 √d?多头注意力到底有啥用?
人工智能·线性代数·机器学习·矩阵
18538162800于2 天前
批量剪辑矩阵分发系统源码搭建,支持OEM
线性代数·矩阵
菜还不练就废了3 天前
7.24 C/C++蓝桥杯 | 排序算法
c语言·c++·蓝桥杯
Aurora_wmroy3 天前
算法竞赛备赛——【图论】拓扑排序
数据结构·c++·算法·蓝桥杯·图论
点云SLAM3 天前
矩阵中QR算法分解简介和基于Eigen库使用示例
人工智能·线性代数·算法·矩阵·slam·qr矩阵分解算法·数值线性代数