POJ 2823【单调队列】

题意:

给出序列,找出每个连续长度为k的子序列的最大值和最小值。

思路:

裸单调队列...

单调队列这东西用的真的非常局限,大概只能用到这种情景中==

简单说一下维护:

添加元素,为了保持单调性,排除队尾所有比要添加的元素大或者小的元素。

出队,出队之前要保证要出队的元素在当前范围内,如果不在先把不在的都出队。

这题可以只记录索引号,所以内存还是可以优化的,懒得写了。

坑:

复制自己的两段代码忘记改其中一个大于号。WA了一上午。不要不要的。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct st
{
    int num,pos;
};
int tmp[1000010];
st ansma[1000010];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&tmp[i]);
    }
    if(m==0)
    {
        for(int i=0;i<=n;i++)
        {
            printf("%d",tmp[i]);
            if(i!=n)
                printf(" ");
        }
        printf("
");
        for(int i=0;i<=n;i++)
        {
            printf("%d",tmp[i]);
            if(i!=n)
                printf(" ");
        }
        printf("
");
        return 0;
    }
    int st,ed;
    st=1;ed=1;
    ansma[1].num=tmp[1];
    ansma[1].pos=1;
    for(int i=2;i<m;i++)
    {
        while(tmp[i]<=ansma[ed].num&&ed>=st)
        {
            ed--;
        }
        ed++;
        ansma[ed].num=tmp[i];
        ansma[ed].pos=i;
    }
    for(int i=m;i<=n;i++)
    {
        while(tmp[i]<=ansma[ed].num&&ed>=st)
        {
            ed--;
        }
        ed++;
        ansma[ed].num=tmp[i];
        ansma[ed].pos=i;
        while(ansma[st].pos<=i-m&&st<ed)
        {
            st++;
        }
        printf("%d",ansma[st].num);
        if(i!=n)
            printf(" ");
    }
    printf("
");
    st=1;ed=1;
    ansma[1].num=tmp[1];
    ansma[1].pos=1;
    for(int i=2;i<m;i++)
    {
        while(tmp[i]>=ansma[ed].num&&ed>=st)
        {
            ed--;
        }
        ed++;
        ansma[ed].num=tmp[i];
        ansma[ed].pos=i;
    }
    for(int i=m;i<=n;i++)
    {
        while(tmp[i]>=ansma[ed].num&&ed>=st)
        {
            ed--;
        }
        ed++;
        ansma[ed].num=tmp[i];
        ansma[ed].pos=i;
        while(ansma[st].pos<=i-m&&st<ed)
        {
            st++;
        }
        printf("%d",ansma[st].num);
        if(i!=n)
            printf(" ");
    }
    printf("
");
}
原文地址:https://www.cnblogs.com/tun117/p/4944744.html