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

1.单调队列保存的是下标,方便判断时效性
2.三步骤 1 判断队首时效性 2 新元素单调性 3 输出队首
3.手打队列一定要写l<=r!!!并且用while别用if来移动队首 按照最保险的方式打 就像下面的l <= r一样 不要想“至少有一个满足时效性,所以不用打到l<=r” 程序会帮我们判断是否满足正确性 我只需要保证队列不越界就行

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN = 1000000 + 10;
int a[MAXN],l=1,r=0,k,n,mians,maans,q[2*MAXN],p[2*MAXN];
int main() {
    cin >> n >> k;
    for(int i=1; i<=n; i++)
        cin >> a[i];
    for(int i=1; i<=n; i++) {
        while(q[l] < i-k+1 && l <= r) l++; //这个l<=r是必须的 因为队列中有可能全部不满足时效性(当i到达n时不再增加新元素),手打队列一定要用while 条件一定加上l <= r,所以有必要全弹没 而写l<r会强行保留一个 背好板子!
        while(a[i] <= a[q[r]] && l <= r) {
            r--;
        }
        q[++r] = i;
        if(i >= k)
            cout << a[q[l]] << " ";
    }
    cout << endl;
    l = 1, r = 0;
    memset(q,0,sizeof(q));
    for(int i=1; i<=n; i++) {
        while(q[l] < i-k+1 && l <= r) l++;
        while(a[i] >= a[q[r]] && l <= r) {
            r--;
        }
        q[++r] = i;
        if(i >= k)
            cout << a[q[l]] << " ";
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/Fantasy_World/article/details/81585009