【单调队列】第十四届蓝桥杯省赛C++ C组 Java C组/研究生组 Python A组《子矩阵》(C++)

【题目描述】

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

设一个矩阵的价值为其所有数中的最大值和最小值的乘积。

求给定矩阵的所有大小为 a×b (a 行 b 列)的子矩阵的价值的和。

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

【输入格式】

输入的第一行包含四个整数分别表示 n,m,a,b,相邻整数之间使用一个空格分隔。

接下来 n 行每行包含 m 个整数,相邻整数之间使用一个空格分隔,表示矩阵中的每个数

【输出格式】

输出一行包含一个整数表示答案。

【数据范围】

对于 40% 的评测用例,1≤n,m≤100;

对于 70% 的评测用例,1≤n,m≤500;

对于所有评测用例,1≤a≤n≤1000,1≤b≤m≤1000,1≤Ai,j≤

【输入样例】

2 3 1 2
1 2 3
4 5 6

【输出样例】

58

【样例解释】

1×2+2×3+4×5+5×6=58。

【代码】

cpp 复制代码
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;
const int N = 1010, MOD = 998244353;

int n, m, A, B;
int w[N][N];
int rmax[N][N], rmin[N][N];
int q[N];

void get_max(int a[], int b[], int tot, int k)
{
    int hh = 0, tt = -1;
    for (int i = 0; i < tot; i ++ )
    {
        if (hh <= tt && q[hh] <= i - k) hh ++ ;
        while (hh <= tt && a[q[tt]] <= a[i]) tt -- ;
        q[ ++ tt] = i;
        b[i] = a[q[hh]];
    }
}

void get_min(int a[], int b[], int tot, int k)
{
    int hh = 0, tt = -1;
    for (int i = 0; i < tot; i ++ )
    {
        if (hh <= tt && q[hh] <= i - k) hh ++ ;
        while (hh <= tt && a[q[tt]] >= a[i]) tt -- ;
        q[ ++ tt] = i;
        b[i] = a[q[hh]];
    }
}

int main()
{
    scanf("%d%d%d%d", &n, &m, &A, &B);
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < m; j ++ )
            scanf("%d", &w[i][j]);

    for (int i = 0; i < n; i ++ )
    {
        get_max(w[i], rmax[i], m, B);
        get_min(w[i], rmin[i], m, B);
    }

    int res = 0;

    int a[N], b[N], c[N];
    for (int i = B - 1; i < m; i ++ )
    {
        for (int j = 0; j < n; j ++ ) a[j] = rmax[j][i];
        get_max(a, b, n, A);
        for (int j = 0; j < n; j ++ ) a[j] = rmin[j][i];
        get_min(a, c, n, A);
        for (int j = A - 1; j < n; j ++ )
            res = (res + (LL)b[j] * c[j]) % MOD;
    }

    printf("%d\n", res);
    return 0;
}
相关推荐
ASKED_201910 小时前
从排序到生成:腾讯广告算法大赛 2025 baseline解读
人工智能·算法
田梓燊10 小时前
leetcode 160
算法·leetcode·职场和发展
_深海凉_10 小时前
LeetCode热题100-颜色分类
python·算法·leetcode
hetao173383711 小时前
2026-04-09~12 hetao1733837 的刷题记录
c++·算法
6Hzlia11 小时前
【Hot 100 刷题计划】 LeetCode 136. 只出现一次的数字 | C++ 哈希表&异或基础解法
c++·算法·leetcode
MWWZ12 小时前
最近的一些软件更新
opencv·算法·计算机视觉
CoovallyAIHub12 小时前
视频理解新范式:Agent不再被动看视频,LensWalk让它自己决定看哪里
算法·架构·github
汉克老师12 小时前
GESP2024年6月认证C++三级( 第二部分判断题(1-10))
c++·数组·位运算·补码·gesp三级·gesp3级
CoovallyAIHub12 小时前
斯坦福丨AirVLA:将地面机械臂模型迁移至无人机实现空中抓取,成功率从23%提升至50%
算法·架构·github
无限进步_13 小时前
【C++】只出现一次的数字 II:位运算的三种解法深度解析
数据结构·c++·ide·windows·git·算法·leetcode