poj2823 单调队列,双端队列
2018-03-04 19:33
330 查看
其实可以用线段树来做..
这道题的具体做法就是维护一个数组
队头s和队尾t。
我们需要维护两个东西,第一个是单调性,第二个是长度。
我们每次加入一个新值,我们是放到尾部。
这个时候我们维护单调性,从尾部开始把大于当前值的全部删除,反正我们找的是最小值,所以不影响。
之后处理完单调性后我们把新值插入。
插入新值后我们形成了新的滑动区间,记录一下最小元素,也就是队伍头部的元素。
之后我们要处理长度问题。看看当前队伍头部的那个值的位置是否已经出去了,就是已经超出滑动区间了,如果
超出了,我们s++即可。如果没有我们就不用管。
重复这个过程即可
//http://blog.csdn.net/waduan2/article/details/52416523代码
#include<cstring>
#include<cstdio>
#define N 1000050
#define INF 2147483647
using namespace std;
int n,k;
int a
;
struct Elem{
int k,num;
}Queue
;
int l=1,r=1;
inline void GetMin(){
memset(Queue,0,sizeof Queue);
Queue[0].k=-INF;
l=1,r=1;
for(int i=1;i<=k;i++){
while(Queue[r].k>=a[i] && r>=l) r--;
Queue[++r].k=a[i];
Queue[r].num=i;
}
for(int i=k;i<=n;i++){
while(Queue[r].k>=a[i] && r>=l) r--; //维护单调性
Queue[++r].k=a[i];
Queue[r].num=i;
while(Queue[l].num<=i-k) l++; //维护队列下标范围k以内
printf("%d ",Queue[l].k);
}
}
inline void GetMax(){
memset(Queue,0,sizeof Queue);
Queue[0].k=INF;
l=1,r=1;
for(int i=1;i<=k;i++){
while(Queue[r].k<=a[i] && r>=l) r--;
Queue[++r].k=a[i];
Queue[r].num=i;
}
for(int i=k;i<=n;i++){
while(Queue[r].k<=a[i] && r>=l) r--;
Queue[++r].k=a[i];
Queue[r].num=i;
while(Queue[l].num<=i-k) l++;
printf("%d ",Queue[l].k);
}
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",a+i);
GetMin();
printf("\n");
GetMax();
return 0;
}
这道题的具体做法就是维护一个数组
队头s和队尾t。
我们需要维护两个东西,第一个是单调性,第二个是长度。
我们每次加入一个新值,我们是放到尾部。
这个时候我们维护单调性,从尾部开始把大于当前值的全部删除,反正我们找的是最小值,所以不影响。
之后处理完单调性后我们把新值插入。
插入新值后我们形成了新的滑动区间,记录一下最小元素,也就是队伍头部的元素。
之后我们要处理长度问题。看看当前队伍头部的那个值的位置是否已经出去了,就是已经超出滑动区间了,如果
超出了,我们s++即可。如果没有我们就不用管。
重复这个过程即可
//http://blog.csdn.net/waduan2/article/details/52416523代码
#include<cstring>
#include<cstdio>
#define N 1000050
#define INF 2147483647
using namespace std;
int n,k;
int a
;
struct Elem{
int k,num;
}Queue
;
int l=1,r=1;
inline void GetMin(){
memset(Queue,0,sizeof Queue);
Queue[0].k=-INF;
l=1,r=1;
for(int i=1;i<=k;i++){
while(Queue[r].k>=a[i] && r>=l) r--;
Queue[++r].k=a[i];
Queue[r].num=i;
}
for(int i=k;i<=n;i++){
while(Queue[r].k>=a[i] && r>=l) r--; //维护单调性
Queue[++r].k=a[i];
Queue[r].num=i;
while(Queue[l].num<=i-k) l++; //维护队列下标范围k以内
printf("%d ",Queue[l].k);
}
}
inline void GetMax(){
memset(Queue,0,sizeof Queue);
Queue[0].k=INF;
l=1,r=1;
for(int i=1;i<=k;i++){
while(Queue[r].k<=a[i] && r>=l) r--;
Queue[++r].k=a[i];
Queue[r].num=i;
}
for(int i=k;i<=n;i++){
while(Queue[r].k<=a[i] && r>=l) r--;
Queue[++r].k=a[i];
Queue[r].num=i;
while(Queue[l].num<=i-k) l++;
printf("%d ",Queue[l].k);
}
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",a+i);
GetMin();
printf("\n");
GetMax();
return 0;
}
相关文章推荐
- poj2823 单调队列以及双端队列(deque)
- 单调队列(双端队列) poj2823 hdoj3415 hdoj3530
- POJ-2823--Sliding Window--双端队列实现单调队列
- Poj2823 Sliding Window (单调队列)
- 单调队列与滑动窗口(Sliding window, poj2823)
- POJ2823 单调队列
- poj2823,典型的单调队列
- poj2823 单调队列
- poj2823 单调队列 ------scanf/printf/G++/C++
- poj2823 Sliding Windows【单调队列】
- POJ2823 单调队列优化入门
- poj2823_单调队列简单入门
- [poj2823]sliding windows(单调队列模板题)
- 用双端队列实现单调队列
- POJ2823 Sliding Window(单调队列)
- poj2823 单调队列
- 【POJ2823】Sliding Window-单调队列
- POJ2823 Sliding Window (单调队列的基本应用)
- 单调队列--poj2823 Sliding Window
- poj2823(单调队列)