题目不说了,可以用线段树或者单调队列,下面附上代码。

线段树:

#include <iostream>
#include <stdio.h>
#include <algorithm>
/*
AC
线段树每个节点存储对应区间的最大值、最小值,然后直接查询即可。6594MS。
*/
using namespace std;
const int maxn=;
const int INF=0x3f3f3f3f;
int minans[maxn],maxans[maxn];
int small,bigger;
int n,k;
struct Node{
int maxv,minv;
}tree[maxn<<]; void pushUp(int rt){
tree[rt].maxv=max(tree[rt<<].maxv,tree[rt<<|].maxv);
tree[rt].minv=min(tree[rt<<].minv,tree[rt<<|].minv);
} void build(int rt,int L,int R){
if(L==R){
scanf("%d",&tree[rt].minv);
tree[rt].maxv=tree[rt].minv;
return;
}
int mid=(L+R)>>;
build(rt<<,L,mid);
build(rt<<|,mid+,R);
pushUp(rt);
} void query(int rt,int l,int r,int L,int R){
if(l<=L && R<=r){
small=min(small,tree[rt].minv);
bigger=max(bigger,tree[rt].maxv);
return;
}
int mid=(L+R)>>;
if(r<=mid)
query(rt<<,l,r,L,mid);
else if(l>mid)
query(rt<<|,l,r,mid+,R);
else{
query(rt<<,l,r,L,mid);
query(rt<<|,l,r,mid+,R);
}
}
int main()
{
int idx=;
scanf("%d%d",&n,&k);
build(,,n);
for(int i=;i<=n-k+;i++){
bigger=-INF;
small=INF;
query(,i,i+k-,,n);
minans[idx]=small; //存储最小值序列
maxans[idx]=bigger; //存储最大值序列
idx++;
}
for(int i=;i<idx;i++){
if(i==)
printf("%d",minans[i]);
else
printf(" %d",minans[i]);
}
printf("\n");
for(int i=;i<idx;i++){
if(i==)
printf("%d",maxans[i]);
else
printf(" %d",maxans[i]);
}
printf("\n");
return ;
}

单调队列:

#include <iostream>
#include <stdio.h>
/*
AC 5204ms
利用单调队列,分两次处理,第一次求最小值序列,第二次求最大值序列。 以求最小值序列为例:
先处理前k-1个元素,每次从队尾加入队列之前,先与队尾元素比较,若比队尾元素值小,则删去队尾元素,直到有比它小的,或者队列为空,
将该元素插入到队尾。即每次保证队列为单调非减队列,队首元素始终是队列中最小的。 接下来依次读入一个元素,与队尾元素比较,若队尾元素大,则删去队尾元素,直至遇到比要插入的元素小或者队列为空为止,插入该元素。
由于要求的是连续的k个区间,所以还要把队列中在该区间之前的元素删去。
这里有个技巧,也就是队列中,存储的不是元素值,而是在数组中的位置,这样很容易判断某个元素是否在连续的k个区间内,
获取元素值的话,就通过存储的数组下标获取。 求最大值序列的时候,同最小值序列,保证队列为非增队列,即队列的首个元素一定是最大的。 */
using namespace std;
const int maxn=;
int n,k;
int a[maxn]; //n个元素值
int dequeue[maxn]; //单调队列
//求最小值序列
void minans(int k,int n) {
int head=;
int tail=;
//先处理前k-1个元素
for(int i=; i<k-; i++) {
while(head<=tail && a[dequeue[tail]]>=a[i]) {
tail--;
}
tail++;
dequeue[tail]=i; //存储的是元素在a中的索引
}
for(int i=k-; i<n; i++) {
while(head<=tail && a[dequeue[tail]]>=a[i]) {
tail--;
}
tail++;
dequeue[tail]=i;
while(dequeue[head]<i-k+) //将索引在i-k+1之前的元素删去
head++;
printf("%d ",a[dequeue[head]]); //输出队列首个元素,即最小的元素 }
}
//求最大值序列
void maxans(int k,int n) {
int head=;
int tail=;
for(int i=; i<k-; i++) {
while(head<=tail && a[dequeue[tail]]<=a[i]) {
tail--;
}
tail++;
dequeue[tail]=i;
}
for(int i=k-; i<n; i++) {
while(head<=tail && a[dequeue[tail]]<=a[i]) {
tail--;
}
tail++;
dequeue[tail]=i;
while(dequeue[head]<i-k+)
head++;
printf("%d ",a[dequeue[head]]); }
} int main() {
scanf("%d%d",&n,&k);
for(int i=; i<n; i++) {
scanf("%d",&a[i]);
}
minans(k,n);
printf("\n");
maxans(k,n);
//printf("\n");
return ;
}

POJ 2823 Sliding Window (线段树/单调队列)的更多相关文章

  1. POJ 2823 Sliding Window 线段树

    http://poj.org/problem?id=2823 出太阳啦~^ ^被子拿去晒了~晚上还要数学建模,刚才躺在床上休息一下就睡着了,哼,还好我强大,没有感冒. 话说今年校运会怎么没下雨!!!说 ...

  2. POJ 2823 Sliding Window 线段树区间求和问题

    题目链接 线段树区间求和问题,维护一个最大值一个最小值即可,线段树要用C++交才能过. 注意这道题不是求三个数的最大值最小值,是求k个的. 本题数据量较大,不能用N建树,用n建树. 还有一种做法是单调 ...

  3. POJ 2823 Sliding Window 再探单调队列

    重新刷这个经典题,感觉跟以前不一样了,变得更加容易理解了,不讲解了,看代码.注意:要用C++提交,用G++会超时.. 代码: #include <iostream> #include &l ...

  4. PKU 2823 Sliding Window(线段树||RMQ||单调队列)

    题目大意:原题链接(定长区间求最值) 给定长为n的数组,求出每k个数之间的最小/大值. 解法一:线段树 segtree节点存储区间的最小/大值 Query_min(int p,int l,int r, ...

  5. POJ 2823 Sliding Window + 单调队列

    一.概念介绍 1. 双端队列 双端队列是一种线性表,是一种特殊的队列,遵守先进先出的原则.双端队列支持以下4种操作: (1)   从队首删除 (2)   从队尾删除 (3)   从队尾插入 (4)   ...

  6. POJ 2823 Sliding Window 题解

    POJ 2823 Sliding  Window 题解 Description An array of size n ≤ 106 is given to you. There is a sliding ...

  7. 洛谷P1886 滑动窗口(POJ.2823 Sliding Window)(区间最值)

    To 洛谷.1886 滑动窗口 To POJ.2823 Sliding Window 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每 ...

  8. 【BZOJ-2892&1171】强袭作战&大sz的游戏 权值线段树+单调队列+标记永久化+DP

    2892: 强袭作战 Time Limit: 50 Sec  Memory Limit: 512 MBSubmit: 45  Solved: 30[Submit][Status][Discuss] D ...

  9. BZOJ 1012 线段树||单调队列

    非常裸的线段树  || 单调队列: 假设一个节点在队列中既没有时间优势(早点入队)也没有值优势(值更大),那么显然不管在如何的情况下都不会被选为最大值. 既然它仅仅在末尾选.那么自然能够满足以上的条件 ...

随机推荐

  1. DNA RNA

    核糖体没有DNA,但是有RNA(rRNA 核糖体RNA) 有DNA的细胞器是线粒体和叶绿体.

  2. linux IO子系统和文件系统读写流程

        本文转载自:http://blog.csdn.net/kidd_3/article/details/6909097 Technorati 标签: I/O 子系统 --------------- ...

  3. Rhythmbox中文乱码解决办法

    今天在网络上找到了一个比较好的解决Rhythmbox中文乱码的问题的方法 进入你的音乐文件夹执行如下代码: mid3iconv -e GBK *.mp3 如果没有提示多试几次,有可能系统会提示: py ...

  4. .NET中变量的类型问题

    1.JAVA和C# Byte的不同. java里一个byte取值范围是-128~127, 而C#里一个byte是0~255. 首位不同. 但是底层I/O存储的数据是一样的, 比如, 十进制的100, ...

  5. 查看linux系统版本命令

    一.查看内核版本命令: 1) [root@SOR_SYS ~]# cat /proc/version Linux version 2.6.18-238.el5 (mockbuild@x86-012.b ...

  6. 11g RAC R2 体系结构---用户及用户组

    10.2 RAC 到11.2 RAC 用户及用户组的变化: 在10.2 RAC 的部署中,只需要一个用户(oracle)和一个用户组(dba).Database.Clusterware都是用oracl ...

  7. WPF样式——多条件触发器

    希望创建多个条件都为真时才激发的触发器,就需要使用MultiTrigger提供的Condition集合 <Window x:Class="Styles.MultiTrigger&quo ...

  8. c++中string类的详解

    ,<时返回-1,==时返回0  string的子串:string substr(int pos = 0,int n = npos) const;//返回pos开始的n个字符组成的字符串strin ...

  9. iOS7之定制View Controller切换效果

    在iOS5和iOS6前,View Controller的切换主要有4种: 1. Push/Pop,NavigationViewController常干的事儿 2. Tab,TabViewControl ...

  10. Unity3D实现立体迷宫寻宝

    Unity3D实现立体迷宫寻宝 这个小游戏是一个白痴在一个昏暗的房间走动找到关键得分点,然后通关游戏.入门Unity3D做的第一款游戏,比较无聊,但实现了一般的游戏功能.如,人物控制,碰撞检测,主控制 ...