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


    *传送

    **单调队列的模板题(做很多题的前置准备)

    本题我们维护一个从大到小/从小到大的单调队列即可。拿最大值来举例:对于新加进来的数,如果比队尾小我们就加进来,否则为了维护单调性我们从队尾弹出比当前值小的值。不难证明这些弹出的值不会是任何一个滑动窗口的答案。对于窗口的限定长度,我们只需要每次判断队首元素所在位置是否超过窗口长度,超过弹出即可,后输出队首(即当前队列中的最大值)即可。

    代码如下:(感觉还是挺简洁易懂的)

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <queue>
     5 using namespace std;
     6 int q1[1000005],q2[1000005];
     7 int n,k,a[1000005];
     8 void maxx(){
     9     int head=1,t=0;
    10     for (int i = 1;i <= n;i++){
    11         while(head<=t&&q1[head]+k<=i) head++;//查看队首是否超过限定长度,超过就弹出 
    12         while(head<=t&&a[i]>a[q1[t]]) t--;//维护单调性 
    13         q1[++t]=i;
    14         if (i>=k) cout<<a[q1[head]]<<" ";
    15     }
    16 }
    17 void minn(){
    18     int head=1,t=0;
    19     for (int i = 1;i <= n;i++){
    20         while(head<=t&&q2[head]+k<=i) head++;//查看队首是否超过限定长度,超过就弹出 
    21         while(head<=t&&a[i]<a[q2[t]]) t--;//维护单调性 
    22         q2[++t]=i;
    23         if (i>=k) cout<<a[q2[head]]<<" ";
    24     }
    25 }
    26 int main(){
    27     scanf ("%d%d",&n,&k);
    28     for (int i = 1;i <= n;i++) scanf ("%d",&a[i]);
    29     minn();
    30     cout<<endl;
    31     maxx();
    32     return 0;
    33 }
  • 相关阅读:
    一些大佬博客里的个签
    后缀子串排序
    PAT 1024 Palindromic Number[难]
    dp训练
    字符串最长子串匹配dp矩阵[转载]
    最短路径并查集+Floyd[转载]
    素数牛客网[求大数内所有素数]
    sql server 的规格参数,限制等 (zz)
    sql server varchar(max), NVARCHAR(MAX), VARBINARY(MAX) (zz)
    Oracle Data Types NVARCHAR2 (zz)
  • 原文地址:https://www.cnblogs.com/very-beginning/p/12487340.html
Copyright © 2020-2023  润新知