POJ2823 Sliding Window (单调队列)
|
Sliding Window
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 of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves rightwards by one position. Following is an example: The array is [1 3 -1 -3 5 3 6 7], and k is 3.
Your task is to determine the maximum and minimum values in the sliding window at each position. Input The input consists of two lines. The first line contains two integers n and k which are the lengths of the array and the sliding window. There are n integers in the second line.
Output There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values.
Sample Input 8 3 Sample Output -1 -3 -3 -3 3 3 Source POJ Monthly--2006.04.28, Ikki
|
||||||||||||||||||||||||||||||
大意:
看题目中那个表格很容易懂,就是有个滑动区间,每次我们要找到这个区间中的最大值、最小值。
题解:
单调队列。
单调队列是DP优化的一种,能实现O(VN)的多重背包。这题虽然不是DP,不过能怒用一发单调队列。
单调队列是用一个单调的队列来存储必要的元素,并不存储无用的元素。在这题的求最小值的过程中:
元素按顺序读入队列q,当队列为空时直接读入;当队列非空时,若队尾的元素不小于当前要入队的元素,则踢出队尾,直到队尾元素小于要入队的元素或者队为空为止。
再开一个数组p,存储队列中的元素在原数据中的下标。
像这样:
(读元素a[i])
while(l<r && q[r-]>=a[i]) r--;
p[r]=i;
q[r++]=a[i];
然后检查队首,如果p存储的队首的元素下标表示该元素已经滑出区间,则将其踢出,像这样:
(检查队首、踢出过期元素)
while(p[l]<i-k+) l++;///若队首的下标表示它已过期(滑出了区间),弹出队首
经过这2个操作后,q[l]就是所求的当前区间的最小值。然后i++,再进行这2个操作,就能得到下一个最小值。换一个符号就能求最大值了。
这两个操作有什么深意呢?
读取时那样的操作,保证了队列中存储了递增的最小若干个数,在队首能立即得到当前区间最小的数(若那个数已经滑出了区间,则它会被踢出),
当那个数滑出区间时能立即找到下一个最小的数。
就这两个简单的操作,用极低的复杂度,就能完成找区间滑动到每个地方的最小值/最大值!我就问你碉不碉!
代码:
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
using namespace std;
#define ll __int64
#define usint unsigned int
#define mz(array) memset(array, 0, sizeof(array))
#define minf(array) memset(array, inf, sizeof(array))
#define REP(i,n) for(int i=0;i<(n);i++)
#define FOR(i,x,n) for(int i=(x);i<=(n);i++)
#define WR(x) printf("%d ",(x))
#define FR freopen("1.in","r",stdin)
#define FW freopen("1.out","w",stdout) const int maxn=; int n,k;
int a[maxn];///存储数据
int q[maxn];///队列
int p[maxn];///存储a[i]的下标i void gankmin()
{
int i,l=,r=;///l,r为队列头尾
for(i=;i<k-;i++)///先将前k-1个入队
{
while(l<r && q[r-]>=a[i]) r--;///队列有元素时,要保证队尾小于要入队的元素,否则弹出队尾
///意义在于存储递增的最小若干个数,能立即得到当前区间最小的数,
///当那个数滑出区间时能立即找到下一个最小的数
p[r]=i; ///记录a[i]的下标
q[r++]=a[i];///a[i]加入队列
}
for(;i<n;i++)
{
while(l<r && q[r-]>=a[i]) r--;
p[r]=i;
q[r++]=a[i]; while(p[l]<i-k+) l++;///若队首的下标表示它已过期(滑出了区间),弹出队首
WR(q[l]);
}
} void gankmax()
{
int i,l=,r=;
for(i=;i<k-;i++)
{
while(l<r && q[r-]<=a[i]) r--;
p[r]=i;
q[r++]=a[i];
}
for(;i<n;i++)
{
while(l<r && q[r-]<=a[i]) r--;
p[r]=i;
q[r++]=a[i]; while(p[l]<i-k+) l++;
WR(q[l]);
}
} int main()
{
while(scanf("%d%d",&n,&k)!=EOF)
{
REP(i,n)
scanf("%d",&a[i]);
gankmin();
puts("");
gankmax();
puts("");
}
return ;
}
POJ2823 Sliding Window (单调队列)的更多相关文章
- POJ2823 Sliding Window(单调队列)
单调队列,我用deque维护.这道题不难写,我第二次写单调队列,1次AC. -------------------------------------------------------------- ...
- POJ 2823 Sliding Window + 单调队列
一.概念介绍 1. 双端队列 双端队列是一种线性表,是一种特殊的队列,遵守先进先出的原则.双端队列支持以下4种操作: (1) 从队首删除 (2) 从队尾删除 (3) 从队尾插入 (4) ...
- poj 2823 Sliding Window (单调队列入门)
/***************************************************************** 题目: Sliding Window(poj 2823) 链接: ...
- POJ 2823:Sliding Window 单调队列
Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 48930 Accepted: 14130 ...
- POJ 2823 Sliding Window (单调队列)
单调队列 加了读入挂比不加更慢.... 而且这份代码要交c++ 有大神G++跑了700ms..... orzorzorz #include<iostream> #include<cs ...
- POJ 2823 UESTCoj 1221 Sliding Window 单调队列 经典入门题
题意:给出一个序列,求出每连续k个数字中最大的数和最小的数. 这是道单调队列裸题,直接写就行了. 本来用deque写出来后,发现在poj上硬是超时了,在discuss上看很多人也在抱怨超时的问题,据说 ...
- POJ2823 Sliding Window(单调队列)
题目要输出一个序列各个长度k的连续子序列的最大值最小值. 多次RMQ的算法也是能过的,不过单调队列O(n). 这题,队列存元素值以及元素下标,队尾出队维护单调性然后入队,队首出队保持新元素下标与队首元 ...
- [POJ2823]Sliding Window 滑动窗口(单调队列)
题意 刚学单调队列的时候做过 现在重新做一次 一个很经典的题目 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗 ...
- [POJ2823] Sliding Window 「单调队列」
我们从最简单的问题开始: 给定一个长度为N的整数数列a(i),i=0,1,...,N-1和窗长度k. 要求: f(i) = max{ a(i-k+1),a(i-k+2),..., a(i) },i ...
随机推荐
- 预备作业02:成功经验与C语调查20155230
成功的经验 在写这一次的博客之前,我看了一部分同学所写的博客.因为我不懂关于自己更优秀的技能这一栏要怎么写,所以想要去找能以借鉴的东西.看完发现,这些同学在介绍自己技能时更多的是写自己在某一领域的成就 ...
- 动态下载苹果系统提供的多种中文字体(适合对字体有较多需求的应用比如阅读类的app)
链接:https://developer.apple.com/library/ios/samplecode/DownloadFont/Listings/DownloadFont_ViewControl ...
- 利用javascript和WebGL绘制地球 【翻译】
利用javascript和WebGL绘制地球 [翻译] 原翻译:利用javascript和WebGL绘制地球 [翻译] 在我们所有已知的HTML5API中,WebGL可能是最有意思的一个,利用这个AP ...
- [原创]Net实现Excel导入导出到数据库(附源码)
关于数据库导出到Excel和SQLServer数据导出到Excel的例子,在博客园有很多的例子,自己根据网上搜集资料,自己做了亦歌简单的demo,现在分享出来供初学者学习交流使用. 一.数据库导入导出 ...
- 打造自己的MyLifeOrganized 2(MLO2)云同步
0x01 官方云同步,付费也很卡 MyLifeOrganized(MLO)是Windows平台下强大的GTD软件,PC版本和Android版本需要分别购买授权,云同步还要再买包月或包年服务真不便宜,关 ...
- Deep Learning 论文解读——Session-based Recommendations with Recurrent Neural Networks
博客地址:http://www.cnblogs.com/daniel-D/p/5602254.html 新浪微博:http://weibo.com/u/2786597434 欢迎多多交流~ Main ...
- iOS -- 生成有logo的二维码
- (void)createLogoImage { NSArray *filter = [CIFilter filterNamesInCategory:kCICategoryBuiltIn]; NSL ...
- window下为apache配置ssl证书
转载自 子非鱼 的博客稍作修改 第一步:依赖 配置Apache服务器支持https协议和SSL证书,最基本的要求是Apache包含openssl模块.还好apache/bin目录下有libeay32. ...
- MVC2 Area实现网站多级目录
Areas是ASP.NET Mvc 2.0版本中引入的众多新特性之一,它可以帮你把一个较大型的Web项目分成若干组成部分,即Area.实现Area的功能可以有两个组织形式: 在1个ASP.NET Mv ...
- 利用css3实现超出文本指定行数与省略号效果
<style> .text1 {/*单行*/ width:200px; overflow:hidden; text-overflow:ellipsis; -o-text-overflow: ...