单调栈和单调队列

一、单调栈

1、使用场景

解决元素左 / 右侧第一个比他大 / 小的数字。

2、原理解释

用栈解决,目标是栈顶存储答案。

以元素左侧第一个比他小为例:

(1)遍历顺序一定是从左向右。

(2)由于栈顶一定是答案,所以如果栈顶比遍历到的元素大或相等,那就是不合法的,此时一直出栈。 

(3)一直到栈空或栈顶比元素小,分别表示元素左边没有数比元素小和元素左边有数比元素小。更新答案。

(4)此时不管怎么样都把元素入栈,因为这个元素可能会是之后的答案。

3、代码

例题:单调栈

P5788 【模板】单调栈 - 洛谷

// https://www.luogu.com.cn/problem/P5788
#include "bits/stdc++.h"
using namespace std;
// 找到右边大的数
// 除非我遍历到的这个数比顶大我才一直出栈(循环解决),栈为空那就是右边没有比我大的我入栈,栈不为空那说说明右边有比我大的我入栈
const int N = 1e7;
int a[N];
int ans[N];int main()
{int n;cin >> n;for(int i = 1; i <= n; i++)cin >> a[i];stack<int> st;for(int i = n; i >= 1; i--){while(st.size() && a[st.top()] <= a[i])st.pop();if(st.empty()){st.push(i);ans[i] = 0;}else {ans[i] = st.top();st.push(i);}}for(int i = 1; i <= n; i++){cout << ans[i] << ' ';}return 0;
}

4、例题

发射站

P1901 发射站 - 洛谷

// https://www.luogu.com.cn/problem/P1901
#include "bits/stdc++.h"
using namespace std;
#define ll long long
// 两个数组:
// 左边离塔最近的高于这个塔的下标
// 右边离塔最近的高于这个塔的下标
// 两个栈分别找到
// 加能量应该是左边比塔高的那个塔加这个塔的能量,top += i
const int N = 1e6 + 10;int sum[N]; // 对应下标的塔接受的能量
int v[N]; // 塔的高度
int e[N]; // 塔的能量
int ans = 0;
int main()
{int n;cin >> n;for(int i = 1; i <= n; i++)cin >> v[i] >> e[i];stack<int> st1;stack<int> st2;for(int i = 1; i <= n; i++){while(st1.size() && v[i] >= v[st1.top()])st1.pop();if(st1.size()){sum[st1.top()] += e[i];}st1.push(i);}for(int i = n; i >= 1; i--){while(st2.size() && v[i] >= v[st2.top()])st2.pop();if(st2.size()){sum[st2.top()] += e[i];}st2.push(i);}for(int i = 1; i <= n; i++){ans = max(ans, sum[i]);}cout << ans;return 0;
}

二、单调队列

1、使用场景

滑动窗口极值问题。

2、原理解释

用队列,目标是队头是答案。

以滑动窗口中的极大值为例:

(1)因为队头是窗口中的最大值,所以一个元素要入队尾插那一定是尽可能向前走,即比元素小的或相等的(刚进来的元素不容易被淘汰,所以相等的老东西也要走)全部尾删。

(2)最后队为空或者尾删停下后,更新尾插。

(3)解决完入队逻辑之后还要解决数据过期,即不在窗口内的元素要清除,所以在每次插入新元素之后对于下标过期的数据循环头删。

3、代码

例题:单调队列

P1886 滑动窗口 /【模板】单调队列 - 洛谷

// https://www.luogu.com.cn/problem/P1886
#include "bits/stdc++.h"
using namespace std;
const int N = 1e6 + 10;
int a[N];
// 双端队列,存下标防止数据过期
// 最小值:队为空直接加,来的数比队尾大不一定就不是后面的答案尾插,来的数比队尾小或等于可以竞争这个范围内的最小值,所以一直尾删。每次最后清除所有不合法下标。
// 最大值:队为空直接加,来的数比队尾小不一定就不是后面的答案尾插,来的数比队尾大或等于可以竞争这个范围内的最大值,所以一直尾删。每次最后清除所有不合法下标。
int main()
{int n, k;deque<int> dq1;deque<int> dq2;cin >> n >> k;for(int i = 1; i <= n; i++)cin >> a[i];// 最小for(int i = 1; i <= n; i++){while(dq1.size() && a[i] <= a[dq1.back()]) dq1.pop_back();dq1.push_back(i);while(dq1.front() <= i - k)dq1.pop_front();if(i >= k)cout << a[dq1.front()] << ' ';}cout << endl;// 最大for(int i = 1; i <= n; i++){while(dq2.size() && a[i] >= a[dq2.back()]) dq2.pop_back();dq2.push_back(i);while(dq2.front() <= i - k)dq2.pop_front();if(i >= k)cout << a[dq2.front()] << ' ';}return 0;
}

4、例题

1、质量检测

P2251 质量检测 - 洛谷

// https://www.luogu.com.cn/problem/P2251
#include "bits/stdc++.h"
using namespace std;
const int N = 1e6 + 10;
int a[N];
int main()
{int n, m;cin >> n >> m;for(int i = 1; i <= n; i++)cin >> a[i];deque<int> dq;for(int i = 1; i <= n; i++){while(dq.size() && a[i] <= a[dq.back()])dq.pop_back();dq.push_back(i);while(dq.front() <= i - m)dq.pop_front();if(i >= m)cout << a[dq.front()] << endl;}return 0;
}

2、HISTOGRA - Largest Rectangle in a Histogram

SP1805 HISTOGRA - Largest Rectangle in a Histogram - 洛谷

// https://www.luogu.com.cn/problem/SP1805
#include <iostream>
#include <stack>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int n;
LL h[N];
LL x[N], y[N];
int main()
{
while(cin >> n, n)
{
for(int i = 1; i <= n; i++) cin >> h[i];
// 找左边,⼩
stack<int> st;
for(int i = 1; i <= n; i++)
{
// 单调递增的栈 - 存下标
while(st.size() && h[st.top()] >= h[i]) st.pop();
if(st.size()) x[i] = st.top();
else x[i] = 0;
st.push(i);
}
// 找右边,⼩
while(st.size()) st.pop();
for(int i = n; i >= 1; i--)
{while(st.size() && h[st.top()] >= h[i]) st.pop();
if(st.size()) y[i] = st.top();
else y[i] = n + 1;
st.push(i);
}
LL ret = 0;
for(int i = 1; i <= n; i++)
{
ret = max(ret, h[i] * (y[i] - x[i] - 1));
}
cout << ret << endl;
}
return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/80259.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

查看电脑信息的方法-CPU核心数量、线程数量等

1、查看CPU基本信息 step 1: windows下 “winr” 进入CMD step 2: 查看核心数&#xff1a;wmic cpu get NumberofCores 查看线程数&#xff1a;wmic cpu get NumberOfLogicalProcessors 查看CPU名称&#xff1a;wmic cpu get Name 查看CPU时钟频率&#xff1a;wmic cpu get Ma…

令牌桶和漏桶算法使用场景解析

文章目录 什么时候用令牌桶&#xff0c;什么时候用漏桶算法&#xff1f;&#xff1f;先放结论 两个算法一眼看懂什么时候选令牌桶&#xff1f;什么时候选漏桶&#xff1f;组合用法&#xff08;90% 的真实系统都会这么干&#xff09;小结记忆 对令牌桶和漏桶组合用法再次详细叙述…

uniapp|实现获取手机摄像头权限,调用相机拍照实现人脸识别相似度对比,拍照保存至相册,多端兼容(APP/微信小程序)

基于uniapp以及微信小程序实现移动端人脸识别相似度对比,实现摄像头、相册权限获取、相机模块交互、第三方识别集成等功能,附完整代码。 目录 核心功能实现流程摄像头与相册权限申请权限拒绝后的引导策略摄像头调用拍照事件处理人脸识别集成图片预处理(Base64编码/压缩)调用…

OpenCV CUDA 模块中用于在 GPU 上计算两个数组对应元素差值的绝对值函数absdiff(

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 void cv::cuda::absdiff 是 OpenCV CUDA 模块中的一个函数&#xff0c;用于在 GPU 上计算两个数组对应元素差值的绝对值。 该函数会逐元素计算两…

Rust 数据结构:HashMap

Rust 数据结构&#xff1a;HashMap Rust 数据结构&#xff1a;HashMap创建一个新的哈希映射HashMap::new()将元组变成哈希表 访问哈希映射中的值哈希映射和所有权更新哈希映射重写一个值仅当键不存在时才添加键和值基于旧值更新值 散列函数 Rust 数据结构&#xff1a;HashMap …

【从设置到上传的全过程】本地多个hexo博客,怎么设置ssh才不会互相影响

偶然间&#xff0c;想多建一个博客&#xff0c;但电脑已经有一个博客了&#xff0c;怎么设置ssh才不会互相影响呢&#xff1f; 在 Windows 系统上设置多个 Hexo 博客的 SSH 配置&#xff0c;避免互相影响&#xff0c;通常户就需要为每个博客配置不同的 SSH 密钥&#xff0c;并…

【时时三省】(C语言基础)字符数组应用举例2

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 例题&#xff1a; 有3个字符串&#xff0c;要求找出其中“最大”者。 解题思路&#xff1a; 可以设一个二维的字符数组str&#xff0c;大小为320&#xff0c;即有3行20列&#xff08;每一…

2025认证杯挑战赛第二阶段B题【 谣言在社交网络上的传播 】原创论文讲解(含完整python代码)

大家好呀&#xff0c;从发布赛题一直到现在&#xff0c;总算完成了认证杯数学中国数学建模网络挑战赛第二阶段B题目谣言在社交网络上的传播完整的成品论文。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半…

Qt功能区:Ribbon使用

Ribbon使用 1. Ribbon功能区介绍1.1 样式 2. 基本功能区设置2.1 安装动态库&#xff08;推荐&#xff09;2.2 在MainWindow中使用Ribbon2.3 在QWidget中使用SARibbonBar2.4 创建Category和Pannel2.5 ContextCategory 上下文标签创建 2.6 ApplicationButton2.7 QuickAccessBar和…

Ubnutu ADB 无法识别设备的解决方法

1. 正确安装adb 下载地址 2. 检查 Linux 是否识别设备 lsusb通过上述指令&#xff0c;分别查询插入、断开设备的usb设备表&#xff0c;如下所示&#xff1a; # 插入设备 adbc:~$ lsusb Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 011:…

C# 实现雪花算法(Snowflake Algorithm)详解与应用

在现代分布式系统中&#xff0c;生成全局唯一的标识符&#xff08;ID&#xff09;是一个非常重要的问题。随着微服务架构和分布式系统的普及&#xff0c;传统的单机数据库生成 ID 的方式已无法满足高并发和高可用的需求。为了解决这个问题&#xff0c;Twitter 提出了 雪花算法&…

STM32+ESP8266连接onenet新平台

若该文为原创文章&#xff0c;转载请注明原文出处。 阿里云物联网平台无法开通了&#xff0c;所以尝试使用onenet平台。 一、硬件 1、STM32F103C8T6最⼩系统板 2、ESP-01S 3、DHT11 二、软件 1、KEIL5.29 2、Token生成工具 3、app inventor 三、原理 四、平台搭建 1、注…

深入解析Spring Boot与Redis集成:高效缓存实践

深入解析Spring Boot与Redis集成&#xff1a;高效缓存实践 引言 在现代Web应用开发中&#xff0c;缓存技术是提升系统性能的重要手段之一。Redis作为一种高性能的键值存储数据库&#xff0c;广泛应用于缓存、会话管理和消息队列等场景。本文将详细介绍如何在Spring Boot项目中…

Python自学笔记3 常见运算符

常用运算符 加减法 python的自动数据类型转换 整形转为浮点型 实数转为复数 数字类型不能和浮点数类型相加减 乘除法 数据转换基本同加减法&#xff0c; 但字符串可以和整数相加减&#xff0c;作用是字符串的自我复制 反斜杠 成员运算符 判断一个元素是不是一个序列的成员…

[特殊字符]接口测试用例设计指南:全面覆盖与精准验证

一、接口测试的核心价值 接口作为系统间通信的桥梁&#xff0c;其稳定性和准确性直接影响业务功能。通过科学设计的测试用例&#xff0c;可以提前暴露接口潜在缺陷&#xff0c;降低上下游系统的耦合风险。本文将系统讲解接口测试的用例设计策略&#xff0c;覆盖查询类接口与操…

[SpringBoot]Spring MVC(2.0)

紧接上文&#xff0c;这篇我们继续讲剩下的HTTp请求 传递JSON数据 简单来说&#xff1a;JSON就是⼀种数据格式,有⾃⼰的格式和语法,使⽤⽂本表⽰⼀个对象或数组的信息,因此JSON本质是字符串. 主要负责在不同的语⾔中数据传递和交换 JSON的语法 1. 数据在 键值对(Key/Value) …

锚点跳转跟踪#

一、html <div ref"computingref"><section id"section1"> </section><section id"section2"> </section><section id"section3"> </section> </div><div class"nav-list&q…

一文了解多模态大模型LLaVA与LLaMA的概念

目录 一、引言 二、LLaVA与LLaMA的定义 2.1 LLaMA 2.2 LLaVA 2.3 LLaVA-NeXT 的技术突破 三、产生的背景 3.1 LLaMA的背景 3.2 LLaVA的背景 四、与其他竞品的对比 4.1 LLaMA的竞品 4.2 LLaVA的竞品 五、应用场景 5.1 LLaMA的应用场景 5.2 LLaVA的应用场景 六…

【LLM】大模型算力基础设施——核心硬件GPU/TPU,架构技术NVLink/RDMA,性能指标FP64/FLOPS(NVIDIA Tesla型号表)

【LLM】大模型算力基础设施——核心硬件GPU/TPU&#xff0c;架构技术NVLink/RDMA&#xff0c;性能指标FP64/FLOPS&#xff08;NVIDIA Tesla型号表&#xff09; 文章目录 1、核心硬件GPU/TPU&#xff0c;NVIDIA Tesla2、集群架构设计 NVLink / RDMA / Alluxio3、性能关键指标&am…

spark的Standalone模式介绍

Apache Spark 的 Standalone 模式是其自带的集群管理模式&#xff0c;无需依赖外部资源管理器&#xff08;如 YARN 或 Mesos&#xff09;&#xff0c;可快速部署和运行 Spark 集群。以下是对 Standalone 模式的详细介绍&#xff1a; 1. 核心组件 Master 节点 集群的主控制器…