单调队列 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;
}
时间: 2024-10-07 01:46:36

单调队列 POJ 2823的相关文章

[单调队列] poj 2823 Sliding Window

题意: 给你n个数和一个k 把n分成连续的n-k+1个区间 第一行按顺序输出每个区间的最小值,第二行是最大值. 思路: 单调队列的模板题,这里注意的是插入队尾的时候需要二分加速 代码: #include"stdio.h" #include"algorithm" #include"string.h" #include"iostream" #include"queue" #include"map&qu

[ACM] poj 2823 Sliding Window(单调队列)

Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 36212   Accepted: 10723 Case Time Limit: 5000MS Description An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left

POJ 2823 Sliding Window(单调队列)

[题目链接] http://poj.org/problem?id=2823 [题目大意] 给出一个数列,问每k个数总最小值和最大值分别是多少 [题解] 单调队列顺序维护需求,时间节点超过k的点就出队 我们维护两次单调队列,用xor的小trick可以降低码量. [代码] #include <cstdio> #include <algorithm> using namespace std; const int MAX_N=1000010; int n,k; int a[MAX_N],b

[ACM] poj 2823 Sliding Window (单调队列)

高一时,学校组织去韶山游玩,我没去,这次趁着五一,总算去了我心心念念的韶山.其实我知道所有的景点都是差不多的,可是因为电视剧<恰同学少年>,让我对毛泽东有了进一层的了解,所以,我一直都想去看看. 有两个同学一男一女是我理想的旅友,可是女生不想去,而男士回家了.所以,我独自一人去了. 准备工作:一小包饼干,一小包山楂片,两个苹果,一瓶水,帽子(防晒),墨镜(装酷) 早晨5:30起床了,洗漱完毕,吃完早餐,赶到公交车站牌那里,才6点过几分.公交车6:31才到,等了近半个小时(公交车上明明说是6:0

poj 2823 Sliding Window (单调队列入门)

1 /***************************************************************** 2 题目: Sliding Window(poj 2823) 3 链接: http://poj.org/problem?id=2823 4 题意: 给一个数列,找所有连续k个数的最小值和最大值. 5 算法: 单调队列(入门) 6 ******************************************************************

POJ 2823 Sliding Window 单调队列题解

本题是单调队列题解的入门,当然也可以使用RMQ 和 线段树,不过速度都没有单调队列那么快. 单调队列难点: 1 如何入列,保存数据 -- 最小单调队列的时候, 所有数都入列一次,在新的数据准备入列的时候,增加判断,如果当前数值小于队尾数值,那么队尾数值就出列.空队列的时候直接入列. 2 保存的数列是什么样的? 举例吧: 1 3 -1 -3 5 3 6 7 构建最小单调队列 第一个数值1的时候,空队列,那么入列,得到: 1 第二个数值3, 因为大于1:那么1不用出列,直接入列,得到: 1 3 第三

POJ 2823 Sliding Window 【单调队列】

题目链接:http://poj.org/problem?id=2823 题目大意:给出一组数,一个固定大小的窗口在这个数组上滑动,要求出每次滑动该窗口内的最大值和最小值. 这就是典型的单调队列,单调队列的作用就在此.单调队列的队首为区间内的最值,但是整个队列不用保持单调. 用两个队列分别处理最大值和最小值,在此说明一下最大值: 往队列中添加值num时,从队尾开始扫,直到遇到一个小于num的d值,将num插入d的后一位.之后的元素全部无效化(不管后面的元素就行).查找最大值的时候,从队首开始找,如

poj 2823 Sliding Window 单调队列或线段树

题目链接:http://poj.org/problem?id=2823 Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 38315   Accepted: 11350 Case Time Limit: 5000MS Description An array of size n ≤ 106 is given to you. There is a sliding window of size k

Sliding Window POJ - 2823 单调队列模板题

Sliding Window POJ - 2823 单调队列模板题 题意 给出一个数列 并且给出一个数m 问每个连续的m中的最小\最大值是多少,并输出 思路 使用单调队列来写,拿最小值来举例 要求区间最小值 就是维护一个单调递增的序列 对于样例 8 3 1 3 -1 -3 5 3 6 7 我们先模拟一遍 1.队列为空 1 进队 队列:1 2.3>队尾元素 3 进队 队列: 1 3 3.-1小于队尾元素,一直从尾部出队知道找到比-1小的元素或者队列为空 队列:-1 当队列中元素大于m的时候从队头删