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


单调队列

一种需要 人工 根据一定条件, 来筛除一些队列中已经没有资格再混下去的元素的数据结构

张三原本在学校的 OI 队伍, 但天天不思进取, 上课只会打小游戏, 结果......
身为高二学长的他竟然连高一新晋的 OIer 都比不过, 于是他们学校的 yxf 老师就将他开除了队伍, 因为 新晋OIer年纪比他小, 能力比他强, 张三的整体价值已经比不过新晋OIer了 QwQ

蒟蒻代码

#include <bits/stdc++.h>
#define re register
using namespace std;

const int N=1e6+5;
int n,k;
int q[N];   // 存储元素索引, 方便判断出队
int head,tail;
int a[N];

void monotoneMin(){
    // memset(q,0,sizeof(q));
    head=1, tail=0;
    for(re int i=1;i<=n;i++){
        while(head<=tail && a[q[tail]]>=a[i]) tail--;
        q[++tail]=i;
        while(head<=tail && q[head]+k<=i) head++;
        if(i>=k) cout<<a[q[head]]<<" ";
    }
    cout<<endl;
}

void monotoneMax(){
    // memset(q,0,sizeof(q));
    head=1, tail=0;
    for(re int i=1;i<=n;i++){
        while(head<=tail && a[q[tail]]<=a[i]) tail--;
        q[++tail]=i;
        while(head<=tail && q[head]+k<=i) head++;
        if(i>=k) cout<<a[q[head]]<<" ";
    }
    cout<<endl;
}

int main()
{
    ios::sync_with_stdio(0);
    clock_t c1 = clock();
#ifdef LOCAL
    freopen("data.in","r",stdin);
    freopen("data.out","w",stdout);
#endif
    // ======================================================================
    cin>>n>>k;
    for(re int i=1;i<=n;i++) cin>>a[i];
    monotoneMin();
    monotoneMax();
    // ======================================================================
end:
    cerr << "Time Used:" << clock() - c1 << "ms" << endl;
    return 0;
}
上一篇:go tail 使用


下一篇:P2032 扫描