单调队列——定长区间最值问题

本文介绍了如何使用单调队列解决定长区间最值问题,包括线段树、多重集和单调队列的简介、操作及应用,强调单调队列在时间复杂度上的优势。
摘要由CSDN通过智能技术生成

本文同步发表于我的 洛谷博客

一、引入

1.1 定长滑窗问题:

给出一列 n n n 个正整数,和一个固定长度为 k k k 的滑动窗口, 从左到右在数列中滑动这个窗口,找到数列中每个窗口内的最大值。

即对于给定数列 A 1 ∼ A n A_1\sim A_n A1An ( 1 ≤ n ≤ 1 0 7 ) (1\le n\le 10^7) (1n107),求每一个 f i = min ⁡ j = i − k + 1 i A j f_i=\min\limits_{j=i-k+1}^{i}A_j fi=j=ik+1miniAj

二、数据维护

2.0 线段树,RMQ

这两者与 2.1 都是 Θ ( n log ⁡ n ) \Theta(n\log n) Θ(nlogn) 级别的复杂度,且代码量较大,因此略过。

2.1 多重集

2.1.1 简介

multiset 是 STL 容器中的一种,中文名为多重集。多重集是按照特定顺序存储元素的容器,其中多个元素可以具有相等的值。

其底层数据结构为红黑树,是一种高度平衡的二叉搜索树,因此插入,搜索和删除都是 Θ ( log ⁡ n ) \Theta (\log n) Θ(logn) 的复杂度,而对于根节点的访问则是 Θ ( 1 ) \Theta(1) Θ(1) 的。

2.1.2 解决方法

每一次插入新的元素,并删除旧元素。由于 multiset 自动按从小到大进行排序,因此一段定长区间的最大值即为 *s.rbegin()

2.1.3 代码

multiset<int,greater<int> > s; //从大到小排序,不去重 
inline void Multiset(){
   
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++) scanf("%d",&x[i]);//input
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值