题意:求每个长度为k的数组的最大值和最小值

思路:

1.用线段树创建维护最大值和最小值,遍历询问,简单复习了一下...有点手生

2.单调队列:

可以看一下详解

单调队列顾名思义就是一个单调递增或者递减的队列,我们可以通过队列瞬间得到当前队列的最大值和最小值。以查找当前区间最小值为例,我们需要维护一个递增的队列,那么当前队列队首就是最小值。在维护队列的过程中要注意:

1、如果队列的长度一定,要判断队首元素是否在规定范围内,如果超范围则队首移动,直到在范围内为止。

2、每次加入元素时和队尾比较,如果队尾元素大于要插入的元素且队列非空,则队尾元素依次出队,直到满足队列的单调性为止,这是为了保证队列的单调性。

线段树:

#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int N = 1e6+5;
int n,k,Max[N<<2],Min[N<<2],ansMa[N],ansMi[N],cnt;
void build(int l,int r,int rt){
if(l == r){
int a;
scanf("%d",&a);
Max[rt] = Min[rt] = a;
return;
}
int m = (l + r) / 2;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
Max[rt] = max(Max[rt<<1],Max[rt<<1|1]);
Min[rt] = min(Min[rt<<1],Min[rt<<1|1]);
}
int queryMa(int L,int R,int l,int r,int rt){
if(l == r) return Max[rt];
if(L <= l && R >= r){
return Max[rt];
}
int m = (l + r) / 2;
int MAX = -1e8;
if(L <= m) MAX = max(MAX,queryMa(L,R,l,m,rt<<1));
if(R > m) MAX = max(MAX,queryMa(L,R,m+1,r,rt<<1|1));
return MAX;
}
int queryMi(int L,int R,int l,int r,int rt){
if(l == r) return Min[rt];
if(L <= l && R >= r){
return Min[rt];
}
int m = (l + r) / 2;
int MIN = 1e8;
if(L <= m) MIN = min(MIN,queryMi(L,R,l,m,rt<<1));
if(R > m) MIN = min(MIN,queryMi(L,R,m+1,r,rt<<1|1));
return MIN;
}
int main(){
while(~scanf("%d%d",&n,&k)){
build(1,n,1);
for(int i = 1,j = k;i <= n-k+1;i++,j++){
ansMa[i] = queryMa(i,j,1,n,1);
ansMi[i] = queryMi(i,j,1,n,1);
}
for(int i = 1;i <= n-k+1;i++){
printf("%d ",ansMi[i]);
}
printf("\n");
for(int i = 1;i <= n-k+1;i++){
printf("%d ",ansMa[i]);
}
printf("\n");
}
return 0;
}

单调队列:

#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int N = 1e6+5;
int a[N],q[N],pos[N],n,k;
int MAX[N],MIN[N];
void get_max(){ //单调递减队列
int head,tail;
head = tail = 0; //tail指向队尾(空)
for(int i = 1;i < k;i++){
while(head < tail && q[tail - 1] <= a[i]) //保证递减
tail--;
q[tail] = a[i];
pos[tail++] = i; //记录个数的位置,为后续查找q[head]是否超出范围准备
}
for(int i = k;i <= n;i++){
while(head < tail && q[tail - 1] <= a[i])
tail--;
q[tail] = a[i];
pos[tail++] = i;
while(head < tail && pos[head] < i-k+1)
head++;
MAX[i-k] = q[head];
}
for(int i = 0;i < n-k+1;i++) printf("%d ",MAX[i]);
printf("\n");
}
void get_min(){ ////单调递增队列
int head,tail;
head = tail = 0;
for(int i = 1;i < k;i++){
while(head < tail && q[tail - 1] >= a[i]) //保证递增
tail--;
q[tail] = a[i];
pos[tail++] = i;
}
for(int i = k;i <= n;i++){
while(head < tail && q[tail - 1] >= a[i])
tail--;
q[tail] = a[i];
pos[tail++] = i;
while(head < tail && pos[head] < i-k+1)
head++;
MIN[i-k] = q[head];
}
for(int i = 0;i < n-k+1;i++) printf("%d ",MIN[i]);
printf("\n");
}
int main(){
while(~scanf("%d%d",&n,&k)){
for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
get_min();
get_max();
}
return 0;
}

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

  1. POJ 2823 Sliding Window + 单调队列

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

  2. poj 2823 Sliding Window (单调队列入门)

    /***************************************************************** 题目: Sliding Window(poj 2823) 链接: ...

  3. POJ 2823 Sliding Window (单调队列)

    单调队列 加了读入挂比不加更慢.... 而且这份代码要交c++ 有大神G++跑了700ms..... orzorzorz #include<iostream> #include<cs ...

  4. poj 2823 Sliding Windows (单调队列+输入输出挂)

    Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 73426   Accepted: 20849 ...

  5. POJ 2823 Sliding Window 题解

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

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

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

  7. POJ 2823 Sliding Window (线段树/单调队列)

    题目不说了,可以用线段树或者单调队列,下面附上代码. 线段树: #include <iostream> #include <stdio.h> #include <algo ...

  8. POJ 2823 Sliding Window 线段树

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

  9. POJ 2823 Sliding Window(单调队列入门题)

      Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 67218   Accepted: 190 ...

随机推荐

  1. 14nm或于6月量产,中芯首次披露12nm及第二代FinFET "N+1"计划(详细数据)

    日前中芯国际公布2018年度第四季度业绩,实现营收7.88亿美元,14nm工艺进入客户验证阶段,可望于今年6月份量产,且12nm工艺开发取得突破. 根据中芯国际披露的财报,2018年第四季度实现营业收 ...

  2. Ubuntu下安装vsftpd

    1.sudo apt-get install vsftpd 2.修改配置文件 sudo gedit /etc/vsftpd.conf write_enable=YES ls_recurse_enabl ...

  3. Java学习之路-Burlap学习

    今天我们来学一下Burlap. Burlap是一种基于XML远程调用技术,但与其他基于XML的远程技术(例如SOAP或者XML-RPC)不同,Burlap的消息结构尽可能的简单,不需要额外的外部定义语 ...

  4. eclipse整合spring+springMVC+Mybatis

    一.新建Maven项目 点击菜单栏File项,选择New->Project,选中Maven Project,如下图: 二.配置pom.xml <?xml version="1.0 ...

  5. springmvc返回json数据的工具类

    在ssm框架下,MVC向前端返回数据的json工具类代码如下: public class JsonResult<T> { public static final int SUCCESS=0 ...

  6. MongoDB复制集的工作原理介绍(二)

    复制集工作原理 1)数据复制原理 开启复制集后,主节点会在 local 库下生成一个集合叫 oplog.rs,这是一个有限集合,也就是大小是固定的.其中记录的是整个mongod实例一段时间内数据库的所 ...

  7. Vue.Js添加自定义插件

    基于上篇我们讲了 在window下搭建Vue.Js开发环境 我们可以开发自己的vue.js插件发布到npm上,供大家下载使用. 1.首先打开cmd命令窗口,进入我们的工作目录下 执行 cd E:\vu ...

  8. HDU 1432 Lining Up(几何)

    http://acm.hdu.edu.cn/showproblem.php?pid=1432 题目大意: 2维平面上给定n个点,求一条直线能够穿过点数最多是多少. 解题思路: 因为题目给定的n(1~7 ...

  9. centos安装samba

    yum -y install samba samba-client samba-swat /etc/init.d/smb start chkconfig --level 35 smb on cp -p ...

  10. Mybatis—三剑客之generator使用方法

    三剑客之generator主要用于自动生成POJO实体类   准备素材: mybatis-generator-core-1.3.2.jar     mysql-connector-java-5.1.2 ...