关于单调队列的模板问题

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
int a[N], ms[N];
int main()
{
    int n, k;
    cin >> n >> k;
    for(int i = 1; i <= n; i++) cin >> a[i];
    int h = 1, t = 0;
    for(int i = 1; i <= n; i++)
    {
       #1 while(h <= t && a[i] <= a[ms[t]]) t--;
       #2 ms[++t] = i; //要位于队头出前,保证队列内一定有元素,防止++t == h造成的空出影响
       #3 if(ms[h] < i - k + 1) h++;
        if(i >= k) cout << a[ms[h]] << " ";
    }
    puts("");
    h = 1, t = 0;
    for(int i = 1; i <= n; i++)
    {
        while(h <= t && a[i] >= a[ms[t]]) t--;
        ms[++t] = i;
        if(ms[h] < i - k + 1) h++;
        if(i >= k) cout << a[ms[h]] << " ";
    }
    
    
}

直接上结论:

h = 1, t = 0 与 h = 0, t = -1都可以, 没区别。

数组下表如果从1开始,会导致 i - k + 1 在 k = 1的条件下 为 1,而一般数组初始化值为0,这样空元素也可能h++。

对此给出2个解决方案:

1.memset(ms, 0x3f, sizeof ms)。

2. #2语句在#3语句之前,使得开始ms[h] = 1。

总结:

下标从0开始,唯一要求的顺序是:

#1 先于 #2 

下标从1开始:

#1 先于 #2 

#2 先于 #3(除非改初始化值)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值