关于单调队列

本文介绍了单调队列这一数据结构的原理和用途,主要在于找到窗口内的极值,如最大值或最小值。在遍历过程中,通过更新队列来保持其单调性,从而高效地处理动态范围查询。文中给出了C++的代码示例,展示了如何利用单调队列解决特定问题。
摘要由CSDN通过智能技术生成

一篇博客需要一个引领全文的话:

当一个人比你小还比你强,你就该考虑退役了 ! \large\text{当一个人比你小还比你强,你就该考虑退役了 !} 当一个人比你小还比你强,你就该考虑退役了 

−   W h e n   s o m e o n e   i s   y o u n g e r   t h a n   y o u   a n d   b e t t e r   t h a n   y o u ,   i t ′ s   t i m e   t o   c o n s i d e r   r e t i r e m e n t !   − \small{-\ When\ someone\ is\ younger\ than\ you\ and\ better\ than\ you,\ it's\ time\ to\ consider\ retirement!\ -}  When someone is younger than you and better than you, its time to consider retirement! 

这就是单调队列的精髓


原理:

单调队列使用一个队列来实现。

单调队列就是确定了一个框后,从头开始,不断往右滑。通过这个窗口,我们就可以知道此窗口内的极值( m a x , m i n max,min max,min 之类的)。

注:队列里面存的是元素下标,而不是元素本身。

实现:

每次遍历到一个新元素时,从尾段( t t t)开始把比它弱的都干掉( t − − t-- t),然后再把自己存进去( q [   + + t   ] = p q[\ ++t\ ]=p q[ ++t ]=p)。如果头端超出了窗口,就剪掉( h + + h++ h++)。

这样一来,队列的头端就一定是当前这个窗口的极值( q [   h   ] q[\ h\ ] q[ h ])。


代码:

#include<bits/stdc++.h>
using namespace std;
const int N=3e6+10;
int n,l,r,a[N],f[N],h=1,t=1,q[N],ans=-0x3f;
signed main(){
	cin>>n>>l>>r;
	for(int i=0;i<=n;i++)cin>>a[i];
	memset(f,-0x4f,sizeof(f));
	f[0]=0;
	for(int i=l;i<=n;i++){
		while(h<=t&&f[i-l]>=f[q[t]])t--;
		q[++t]=i-l;
		while(q[h]+r<i)h++;
		f[i]=a[i]+f[q[h]];
		if(i>n-r)ans=max(ans,f[i]);
	}
	cout<<ans<<"\n";
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值