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

    维护一个队头和队尾

    单调队列的性质  单调  

    时间  n   

    这边讲维护小的

    因为维护单调  从队尾进去    经过 

     w    1  3  -1 -3  3  3   6   7

    ind   1  2  3  4   5  6   7    8               k=3

    初始话一下

    头  w      1                    尾  

         ind    1           

      w         1     3             因为3比1 大 放在后面

     ind        1     2

      w         1     3                 然后要加入-1  比较  比前面2个都小   所以      -1   

       ind      1     2                                                                               3

    初始化也就完成了

    接下来其实每个入队就和初始化差不多  判断是否比当前的大  大的话 pop  最后放进去 

    然后因为每次队头都是最小的  那么只要这个合法就行了  如果这个下标不在 那个k内 就去掉 

    最大的同理

    #include<stdio.h>
    #include<algorithm>
    #include<stdlib.h>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    #include<iterator>
    #include<stack>
    
    using namespace std;
    
    #define ll   __int64
    #define MAXN  2000010
    #define inf  2000000007
    #define mod 1000000007
    int z[MAXN];
    struct
    {
        int w,ind;
    }q[MAXN];
    int mx[MAXN];
    int mi[MAXN];
    
    int main()
    {
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
            scanf("%d",&z[i]);
        int sz=1;
        int fr=1;
        q[1].w=z[1];
        q[1].ind=1;
        for(int i=2;i<k;i++)
        {
            while(sz>=fr&&q[sz].w>z[i])
                sz--;
            sz++;
            q[sz].w=z[i];
            q[sz].ind=i;
        }
        for(int i=k;i<=n;i++)
        {
            while(sz>=fr&&q[sz].w>z[i])
                sz--;
            sz++;
            q[sz].w=z[i];
            q[sz].ind=i;
            while(q[fr].ind<i-k+1)
                fr++;
            mi[i-k+1]=q[fr].w;
        }
        for(int i=1;i<n-k+1;i++)
            printf("%d ",mi[i]);
        printf("%d
    ",mi[n-k+1]);
        fr=1;
        sz=1;
        q[1].w=z[1];
        q[1].ind=1;
        for(int i=2;i<k;i++)
        {
            while(sz>=fr&&q[sz].w<z[i])
                sz--;
            sz++;
            q[sz].w=z[i];
            q[sz].ind=i;
        }
        for(int i=k;i<=n;i++)
        {
            while(sz>=fr&&q[sz].w<z[i])
                sz--;
            sz++;
            q[sz].w=z[i];
            q[sz].ind=i;
            while(q[fr].ind<i-k+1)
                fr++;
            mx[i-k+1]=q[fr].w;
        }
        for(int i=1;i<n-k+1;i++)
            printf("%d ",mx[i]);
        printf("%d
    ",mx[n-k+1]);
    
        return 0;
    }
  • 相关阅读:
    51 Nod 1086 多重背包问题(单调队列优化)
    51 Nod 1086 多重背包问题(二进制优化)
    51 Nod 1085 01背包问题
    poj 2559 Largest Rectangle(单调栈)
    51 Nod 1089 最长回文子串(Manacher算法)
    51 Nod N的阶乘的长度 (斯特林近似)
    51 Nod 1134 最长递增子序列(经典问题回顾)
    51 Nod 1020 逆序排列
    PCA-主成分分析(Principal components analysis)
    Python中cPickle
  • 原文地址:https://www.cnblogs.com/cherryMJY/p/6678239.html
Copyright © 2011-2022 走看看