洛谷P1886滑动窗口

Posted 那一抹落日的橙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P1886滑动窗口相关的知识,希望对你有一定的参考价值。

这个题数据范围10^6,nlogn很悬,所以我们考虑用单调队列

单调队列的性质,保证队列单调递减/递增,因此我们可以通过维护单调队列,来方便的查询区间最大值、最小值

#include<iostream>
#include<cstdio>
using namespace std;
struct in
{
    int zhi,wei;
}ter[1000010];
int shu[1000010],mi[1000010],mx[1000010],n,k,head,tail;
inline void cl(int x)
{
    while(ter[head].wei<x-k+1&&head<=tail)//凡是在窗口外的一律弹出 
        head++;
}
inline void pu1(int x)
{
    while(shu[x]<ter[tail].zhi&&head<=tail)//保证队列单调递增,凡是比这个数大的就都没有可能成为答案了,因为他们入队在前,值还大,而凡是可以与他们在一个队列里的就意味着有窗口能将他们一起覆盖 
        tail--;
    ter[++tail]=(in){shu[x],x};
    mi[x]=ter[head].zhi;
}
inline void pu2(int x)
{
    while(shu[x]>ter[tail].zhi&&head<=tail)//同理保持单调递减 
        tail--;
    ter[++tail]=(in){shu[x],x};
    mx[x]=ter[head].zhi;
}
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
        scanf("%d",&shu[i]);
    head=tail=1,mi[1]=shu[1],ter[1]=(in){shu[1],1};
    for(int i=2;i<=n;i++)
        cl(i),pu1(i);
    head=tail=1,mx[1]=shu[1],ter[1]=(in){shu[1],1};
    for(int i=2;i<=n;i++)
        cl(i),pu2(i);
    for(int i=k;i<=n;i++)
        printf("%d ",mi[i]);
    printf("\n");
    for(int i=k;i<=n;i++)
        printf("%d ",mx[i]);
    printf("\n");
}

 

以上是关于洛谷P1886滑动窗口的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P1886滑动窗口

洛谷 P1886 滑动窗口

洛谷P1886 滑动窗口 单调队列

洛谷P1886滑动窗口

AC日记——滑动窗口 洛谷 P1886

洛谷 P1886 滑动窗口 (数据与其他网站不同。。)