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

线段树:

#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. flume+kafka (分区实现 默认单分区)

    这篇文章主要是log4j+flume+kafka的内容 首先从从下面的地址下载flume+kafka的插件包 https://github.com/beyondj2ee/flumeng-kafka-p ...

  2. get the runing time of C++ console program.

    // 获取程序运行时间.cpp : 定义控制台应用程序的入口点.// #include "stdafx.h"#include <time.h>#include < ...

  3. const关键字在C和C++区别

    1)C++默认为内部链接:C默认为外部链接2)在C++中,一般一个const不会创建内存空间,而是将其保存在符号表(待看).比如: ; char buf[bufsize]; 这里无需为const创建内 ...

  4. JAVA设计模式(DESIGN PATTERNS IN JAVA)读书摘要 第1部分接口型模式——第4章 外观(Facade)模式

    外观模式就类似于一个工具包,一个类对应一个功能. 外观模式的意图是为子系统提供一个接口,便于它的使用. 书中给出的例子是画一个哑弹的飞行路径, 初始的类的设计是这样的,看下图, ShowFlight类 ...

  5. Atan2

    在三角函数中,两个参数的函数atan2是正切函数的 一个变种.对于任意不同时等于0的实参数x和y,atan2(y,x)所表达的意思是坐标原点为起点,指向(x,y)的射线在坐标平面上与x轴正方向之间 的 ...

  6. GitHub for Windows离线安装的方法

    这几天一直在尝试安装GitHub for windows ,安装程序是从https://windows.github.com/ 下载到的OneClick 部署程序,版本号为2.11.0.5.可能是因为 ...

  7. Nginx启动SSL功能,并进行功能优化,你看这个就足够了

    一:开始Nginx的SSL模块 1.1 Nginx如果未开启SSL模块,配置Https时提示错误 nginx: [emerg] the "ssl" parameter requir ...

  8. Redis源码研究--redis.h

    ------------7月3日------------ /* The redisOp structure defines a Redis Operation, that is an instance ...

  9. php session偶尔写入失败的原因

    session_start(); var_dump($_SESSION); $key = sprintf('%05d', mt_rand(0, 99999)); $key = strval($key) ...

  10. 比较不错的JS 曲线图

    fashion chart   falsh文件支持,无需考虑兼容 Highcharts(纯JS,很漂亮 效果很好) Highcharts是一个制作图表的纯Javascript类库,主要特性如下: 兼容 ...