【单调队列】第十四届蓝桥杯省赛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;
}
相关推荐
leisoo809726 分钟前
财报数据怎么排雷本地化Python构建财务异常预警系统
人工智能·python·算法
qz_Serene2 小时前
C++:类和对象(上)
开发语言·c++
luj_17683 小时前
塔防牌:策略与卡牌的智慧碰撞
服务器·c语言·开发语言·经验分享·算法
郝学胜-神的一滴3 小时前
干货版《算法导论》17:二叉树核心原理、遍历逻辑与高阶实操全解
数据结构·c++·python·算法·计算机·编程
爱编程的小新☆3 小时前
【LeetCode】从递归到 Flood Fill:5 道题吃透 DFS 的选择、回溯与标记
java·算法·leetcode·深度优先·回溯·flood fill
Water_Sunzhipeng3 小时前
2024牛客暑期多校训练营1
算法
hetao17338374 小时前
2026-08-09~08-14 hetao1733837 的刷题记录
c++·算法
技术小黑4 小时前
RNN算法实战系列06 | LSTM 实现糖尿病探索与预测
rnn·算法·lstm
疯狂打码的少年4 小时前
【数据结构】二叉树的性质(五大性质+计算)
数据结构·笔记·算法
wabs6664 小时前
关于图论【A*算法 | 卡码网127.骑士的攻击的思考】
数据结构·算法·图论·卡码网·广搜的改进版