单调队列 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\n",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\n",mx[n-k+1]);

    return 0;
}

 

posted on 2017-04-07 15:15  HelloWorld!--By-MJY  阅读(150)  评论(0编辑  收藏  举报

导航