前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【POJ 2823】Sliding Window(单调队列/堆)

【POJ 2823】Sliding Window(单调队列/堆)

作者头像
饶文津
发布2020-06-02 12:17:00
2340
发布2020-06-02 12:17:00
举报
文章被收录于专栏:饶文津的专栏饶文津的专栏

题意

给定n,k,求滑窗[i,i+k-1]在(1<=i<=n)的最大值最小值。

题解

单调队列或堆。 入队的条件是当前的进入了滑窗范围。 出队的条件是当前不在滑窗范围。

代码

我用堆写的,但是堆写错了个小地方,查了很久才发现。

代码语言:javascript
复制
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define pii pair<int,int>
#define mp(i,j) make_pair(i,j)
#define N 1000006
using namespace std;
int n,k;
int a[N];
pii q[N];
int back;
void push(pii a,int d){
	q[++back]=a;
	for(int i=back;i>1&&(d?q[i]>q[i>>1]:q[i]<q[i>>1]);i>>=1)
		swap(q[i],q[i>>1]);
}
void pop(int d){	
	swap(q[1],q[back--]);
	for(int i=1;i<=(back>>1);){
		if(d?q[i]>=max(q[i<<1],q[i<<1|1]):q[i]<=min(q[i<<1],q[i<<1|1]))return;//qaq
		if(((i<<1|1)>back)||(d?q[i<<1]>q[i<<1|1]:q[i<<1]<q[i<<1|1])){
			swap(q[i<<1],q[i]);
			i<<=1;
		}else{
			swap(q[i<<1|1],q[i]);
			i=(i<<1|1);
		}
	}
}
int main() {
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		if(i<=k)push(mp(a[i],i),0);
	}
	for(int i=k;i<=n;i++){
		printf("%d ",q[1].first);
		while(back&&q[1].second<=i-k+1)pop(0);
		push(mp(a[i+1],i+1),0);
	}
	puts("");
	back=0;
	for(int i=1;i<=k;i++)push(mp(a[i],i),1);
	for(int i=k;i<=n;i++){
		printf("%d ",q[1].first);
		while(back&&q[1].second<=i-k+1)pop(1);
		push(mp(a[i+1],i+1),1);
	}
	return 0;
}

单调队列,写起来简单多了,而且也不会和手写堆一样容易出错。

代码语言:javascript
复制
#include <cstdio>
#define N 1000006
using namespace std;
int n,k;
int a[N],b[N],q[N],head,tail;
int main() {
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=n;i++){
		while(head<tail&&a[i]<q[tail-1])tail--;
		b[tail]=i;
		q[tail++]=a[i];
		while(head<tail&&b[head]<i-k+1)head++;
		if(i>=k)printf("%d ",q[head]);
	}
	puts("");
	tail=head=0;
	for(int i=1;i<=n;i++){
		while(head<tail&&a[i]>q[tail-1])tail--;
		b[tail]=i;
		q[tail++]=a[i];
		while(head<tail&&b[head]<i-k+1)head++;
		if(i>=k)printf("%d ",q[head]);
	}
	return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-02-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题意
  • 题解
  • 代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档