• 【洛谷P1886】滑动窗口——单调队列


    没想到啊没想到,时隔两个月,我单调队列又懵了……

    调了一个小时,最后错在快读,啊!!!!(不过洛谷讨论真好啊,感谢大佬!)

    考前就不推新东西了,好好写写那些学过的东西


     题目点这里(我就不粘了自己点一下看吧)

    这题还有其他奇奇怪怪的做法,比如你可以当做RMQ,用线段树啊ST表啊随便你,不过单调队列就可以了

    单调队列说到底就是个数据结构,就是维护数据的。

    以当前这道题为例:

    它维护的队列一定满足单调性,单调递增或递减,或者自定义一个单调性。

    如何维护呢,假设当前队尾为q [ tail ], 要插入元素为 a [ i ]

    • 若直接插入 a [ i ] 满足其单调性,就直接插入
    • 若不满足,就删掉 q [ tail ] ( tail - - ) ,因为能取到 q [  tail ] 就一定能取到 a [ i ] , 而a [ i ] 更优

    这题既然要求最大值和最小值,就求两遍嘛!

    下面是代码

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    int n,k,a[1000001],q[1000001],p[1000001],head,tail;
    inline int read()
    {
        int x=0;
        char c=getchar();
        int flag=1;
        while (c>'9'||c<'0')
        {
            if (c=='-')
            flag*=-1;
            c=getchar(); 
        } //就是这里!!!!记住它!!! 
        while (c<='9'&&c>='0') x=x*10+c-48,c=getchar();
        x*=flag;
        return x;
    }//这个坑死我的快读啊!!!!!!考前一定要多打几遍 
    int main()
    {
        n=read(); k=read();
        for (int i=1; i<=n; i++)
        a[i]=read();
        // 求 min 
        head=1; tail=0;
        for (int i=1; i<=n; i++)
        {
            while (head<=tail&&q[tail]>=a[i])
            tail--;
            //首先保证不要删过,head<=tail(tail可以等于head)
            //求最小那么单调性就是单调递增 
            q[++tail]=a[i];
            p[tail]=i;//插入队列 
            while (p[head]<=i-k) head++;//更新队头,使最值在区间内 
            if (i>=k) cout<<q[head]<<" ";//k往后每一个i都对应一个窗口,输出队头存储的最值即可 
        }
        cout<<endl;
        head=1,tail=0;
        // 求 max ,类比求 min 
        for (int i=1; i<=n; i++)
        {
            while (head<=tail&&q[tail]<=a[i])
            tail--;
            //最大值就是单调递增 
            q[++tail]=a[i];
            p[tail]=i;
            while (p[head]<=i-k) head++;
            if (i>=k) cout<<q[head]<<" ";
        }
        return 18751214;//快考试啦不要抄答案!!!(给我自己 
    }

    就是这些,CSP快到啦,RP++!!

    惯例

    ありがとうございます

  • 相关阅读:
    Linux下面编译安装ffmpeg
    Fidder简单使用方法(HTTPS抓取和url替换)
    关于一下个阶段的计划
    JAVA的随机的字符串的封装(基本上够用了)
    Shell Script中的间接变量引用
    进程概念
    int main(int argc, char *argv[])的解读
    存储数组数据到SharedPreferences
    C语言中的基本声明
    C中关于指针数组的用法
  • 原文地址:https://www.cnblogs.com/Phantomhive/p/11747542.html
Copyright © 2020-2023  润新知