zoukankan      html  css  js  c++  java
  • 单调队列

     单调队列就是维护一个队列,使得该队列从队首到队尾成单调递增或是单调递减。

     做法就是每向队列里加入一个元素就判断该元素是不是比队尾元素大(以递减序列为例),是的话就将队尾元素出列,直到该元素比队尾元素小,然后将该元素放置队尾。

      这么久了一直不明白单调队列的实现,现在看来,原来这么简单。。。。。

      单调栈的原理相似,只不过一个是栈,一个是队列而已

    两道例题:

    luogu1886

    luogu1714

    代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int N=1000000*2;
     6 int q[N],head,tail,bz[N];
     7 int a[N],n,pos[N],k;
     8 int main()
     9 {
    10   scanf("%d%d",&n,&k);
    11   for(int i=1;i<=n;++i)
    12     scanf("%d",&a[i]);
    13     if(k==1)//日常卡数据,请忽略
    14     {
    15       for(int i=1;i<=n;++i)
    16       printf("%d ",a[i]);
    17       printf("
    ");
    18       for(int i=1;i<=n;++i)
    19       printf("%d ",a[i]);
    20       return 0;
    21     }
    22   q[++tail]=a[1];pos[tail]=1;
    23   for(int i=2;i<k;++i)
    24   {
    25     while(a[i]<q[tail]&&tail>head) --tail;
    26     q[++tail]=a[i];
    27     pos[tail]=i;
    28   }
    29   for(int i=k;i<=n;++i)
    30   {
    31     bz[i-k]=1;
    32     while(bz[pos[head]]==1) head++;
    33      while((a[i]<q[tail]||bz[pos[tail]])&&tail>=head)
    34     --tail;
    35     q[++tail]=a[i];
    36     pos[tail]=i;
    37     printf("%d ",q[head]);
    38   }
    39   printf("
    ");
    40   memset(q,0,sizeof(q));
    41   memset(bz,0,sizeof(bz));
    42   memset(pos,0,sizeof(pos));
    43   tail=1;head=1;
    44   q[++tail]=a[1];pos[tail]=1;
    45   for(int i=2;i<k;++i)
    46   {
    47     while(a[i]>q[tail]&&tail>=head) --tail;
    48     q[++tail]=a[i];
    49     pos[tail]=i;
    50   }
    51   for(int i=k;i<=n;++i)
    52   {
    53     bz[i-k]=1;
    54     while(bz[pos[head]]==1) head++;
    55      while((a[i]>q[tail]||bz[pos[tail]])&&tail>=head)
    56     --tail;
    57     q[++tail]=a[i];
    58     pos[tail]=i;
    59     printf("%d ",q[head]);
    60   }
    61   return 0;
    62 }
    luogu1886
     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 int n,m;
     5 const int N=500000*2;
     6 int bz[N],pos[N],a[N],q[N],sum[N];
     7 int head=1,tail=0,ans=-0x7fffffff;
     8 int main()
     9 {
    10   scanf("%d%d",&n,&m);
    11   for(int i=1;i<=n;++i)
    12   {
    13     scanf("%d",&a[i]);
    14     sum[i]=a[i]+sum[i-1];
    15   }
    16   m++;
    17   for(int i=1;i<=n;++i)
    18   {
    19     if(i>m) bz[i-m]=1;
    20     while(bz[pos[head]]) head++;
    21     while((sum[i]<q[tail]||bz[pos[tail]])&&tail>=head) tail--;
    22     q[++tail]=sum[i];
    23     pos[tail]=i;
    24     ans=max(ans,sum[i]-q[head]);
    25   }
    26   printf("%d",ans);
    27   return 0;
    28 }
    luogu1714
  • 相关阅读:
    一个简易的四则运算单元...(15.12.15 BUG更新)
    转一个PDevMode格式属性说明...
    正则表达式语法
    模拟键盘发送文字
    一个修改过简化版的InputQuery
    获取进程列表的单元
    获取EMF文件内全部文字, 并按照左上到右下的顺序排序
    非主窗体在任务栏显示按钮
    禁用窗体关闭按钮
    一个支持FMX.Win框架的托盘控件
  • 原文地址:https://www.cnblogs.com/wxyww/p/9420207.html
Copyright © 2011-2022 走看看