POJ2823 单调队列

POJ2823 http://poj.org/problem?id=2823

最基础的单调队列,说是数据结构,其实就是一种更新数组数据的方法。

之前还准备用deque,超时了,直接head,tail快得多。

一直把删除队首过期元素写在删除队尾之前,就一直WA,尼玛换一下顺序就好了。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 //#define OPEN_FILE
 5 using namespace std;
 6 const int MAXN = 1000001;
 7 int n, w;
 8 struct  Node{
 9     int v, p;
10 }a[MAXN], d[MAXN];
11 inline bool cmp(int a, int b){
12     if (a < b) return true;
13     if (a > b) return false;
14     return false;
15 }
16 void work(bool flag)
17 {
18     int i, head, tail;
19     memset(d, 0, sizeof(d));
20     head = tail = 1;
21     d[head] = a[1];
22     for (i = 2; i <= w; i++){
23         while (cmp(d[tail].v, a[i].v) == flag){
24             tail--;
25             if (tail < head) break;
26         }
27         d[++tail] = a[i];
28     }
29     printf("%d", d[head]);
30     for (i = w + 1; i <= n; i++){
31         if (head <= tail){
32             while (cmp(d[tail].v, a[i].v) == flag){
33                 tail--;
34                 if (head > tail) break;
35             }
36         }
37         d[++tail] = a[i];
38         while (d[head].p <= i - w){
39             head++;
40         }
41         printf(" %d", d[head]);
42     }
43 }
44
45 int main()
46 {
47 #ifdef OPEN_FILE
48     freopen("in.txt", "r", stdin);
49     freopen("out.txt", "w", stdout);
50 #endif // OPEN_FILE
51     int i;
52     scanf("%d%d", &n, &w);
53     for (i = 1; i <= n; i++){
54         scanf("%d", &a[i].v);
55         a[i].p = i;
56     }
57     work(false);
58     printf("\n");
59     work(true);
60     printf("\n");
61 }
时间: 2024-12-14 21:17:28

POJ2823 单调队列的相关文章

poj2823单调队列

这个裸题,滑动窗口求最大最小值,单调队列来两边,一次单调递增q[s]就是最小值,一次单调递减q[s]就是最大值 cin会超时,解除同步也没用... #include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cassert> #incl

poj2823(单调队列)

我们知道,上一种算法有一个地方是重复比较了,就是在找当前的f(i)的时候,i的前面k-1个数其它在算f(i-1)的时候我们就比较过了.那么我们能不能保存上一次的结果呢?当然主要是i的前k-1个数中的最大值了.答案是可以,这就要用到单调递减队列. 单调递减队列是这么一个队列,它的头元素一直是队列当中的最大值,而且队列中的值是按照递减的顺序排列的.我们可以从队列的末尾插入一个元素,可以从队列的两端删除元素. 1.首先看插入元素:为了保证队列的递减性,我们在插入元素v的时候,要将队尾的元素和v比较,如

POJ2823 Sliding Window (单调队列)

POJ2823 Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 38342   Accepted: 11359 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 ve

单调队列(双端队列) poj2823 hdoj3415 hdoj3530

单调队列及其应用(双端队列) 单调队列,望文生义,就是指队列中的元素是单调的.如:{a1,a2,a3,a4--an}满足a1<=a2<=a3--<=an,a序列便是单调递增序列.同理递减队列也是存在的. 单调队列的出现可以简化问题,队首元素便是最大(小)值,这样,选取最大(小)值的复杂度便为o(1),由于队列的性质,每个元素入队一次,出队一次,维护队列的复杂度均摊下来便是o(1). 如何维护单调队列呢,以单调递增序列为例: 1.如果队列的长度一定,先判断队首元素是否在规定范围内,如果超范

POJ2823 Sliding Window(单调队列)

单调队列,我用deque维护.这道题不难写,我第二次写单调队列,1次AC. ----------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<deque> #define rep(i,r) for(int i=0;i<r;i++) #define clr(x,c) memset

单调队列 poj2823,fzu1894

题目链接:http://poj.org/problem?id=2823 用RMQ超时了,我想应该是不会的,看discuss说,之前RMQ过了. 维护两个单调队列. 单调递减的队列,每插入一个时: 超过单调队列长度,左移头指针. 第一个或者符合条件,直接加到后面. 否则,一直退: 1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 6 u

POJ2823 Sliding Window (单调队列的基本应用)

题目链接: http://poj.org/problem?id=2823 题意: 给定一个长度为n的序列,求每个长度为k的区间的最大值与最小值 分析: 单调队列的基本应用 代码如下: <span style="font-size:14px;">#include <iostream> #include <cstring> #include <cstdio> #include <queue> #include <vector

poj-2823(单调队列)

题意:给你长度位n的数组,问每个长度为m的段的最值: 解题思路:这道题是单调队列的入门题: #include<iostream> #include<algorithm> #include<queue> #include<cstdio> #define maxn 1000100 using namespace std; struct node { int val; int pos; }a[maxn]; int que[maxn]; int mn[maxn];

【NOIP数据结构专项】单调队列单调栈

[洛谷P1901 ]发射站 http://www.luogu.org/problem/show?pid=1901 题目描述 某地有 N 个能量发射站排成一行,每个发射站 i 都有不相同的高度 Hi,并能向两边(当 然两端的只能向一边)同时发射能量值为 Vi 的能量,并且发出的能量只被两边最近的且比 它高的发射站接收. 显然,每个发射站发来的能量有可能被 0 或 1 或 2 个其他发射站所接受,特别是为了安 全,每个发射站接收到的能量总和是我们很关心的问题.由于数据很多,现只需要你帮忙计 算出接收