POJ 2823 Sliding Window(单调队列 || 线段树)题解
题意:求每个长度为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(单调队列 || 线段树)题解的更多相关文章
- POJ 2823 Sliding Window + 单调队列
一.概念介绍 1. 双端队列 双端队列是一种线性表,是一种特殊的队列,遵守先进先出的原则.双端队列支持以下4种操作: (1) 从队首删除 (2) 从队尾删除 (3) 从队尾插入 (4) ...
- poj 2823 Sliding Window (单调队列入门)
/***************************************************************** 题目: Sliding Window(poj 2823) 链接: ...
- POJ 2823 Sliding Window (单调队列)
单调队列 加了读入挂比不加更慢.... 而且这份代码要交c++ 有大神G++跑了700ms..... orzorzorz #include<iostream> #include<cs ...
- poj 2823 Sliding Windows (单调队列+输入输出挂)
Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 73426 Accepted: 20849 ...
- POJ 2823 Sliding Window 题解
POJ 2823 Sliding Window 题解 Description An array of size n ≤ 106 is given to you. There is a sliding ...
- 洛谷P1886 滑动窗口(POJ.2823 Sliding Window)(区间最值)
To 洛谷.1886 滑动窗口 To POJ.2823 Sliding Window 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每 ...
- POJ 2823 Sliding Window (线段树/单调队列)
题目不说了,可以用线段树或者单调队列,下面附上代码. 线段树: #include <iostream> #include <stdio.h> #include <algo ...
- POJ 2823 Sliding Window 线段树
http://poj.org/problem?id=2823 出太阳啦~^ ^被子拿去晒了~晚上还要数学建模,刚才躺在床上休息一下就睡着了,哼,还好我强大,没有感冒. 话说今年校运会怎么没下雨!!!说 ...
- POJ 2823 Sliding Window(单调队列入门题)
Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 67218 Accepted: 190 ...
随机推荐
- 如何控制dedecms描述的长度?
我们都知道调用dedecms的标题长度可以用titlelen='字符数',{dede:arclist titlelen='10'},表示标题长度为10个字符,也即是5个汉字.如果想要控制描述的调用长度 ...
- wordpress如何正确自动获取中文日志摘要
WordPress 函数 get_the_excerpt() 可以获取日志的摘要,如果没有摘要,它会自动获取内容,并且截取.但是由于无法正确统计中文字符数,我爱水煮鱼撰写了下面这个函数来解决这个问题. ...
- 创建list方法总结
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/sheismylife/article/details/28878593 构建一个list 注意要标记 ...
- 003-spring cloud gateway-概述、Route模型、网关初始化配置过程、基本原理
一.概述 网关服务核心是将进入的请求正确合理的路由到下层具体的服务进行业务处理,由此可见网关服务的核心就是路由信息的构建. Spring Cloud Gateway旨在提供一种简单而有效的方式来路由到 ...
- 智能指针 - 现代C++新特性总结
C++98中的智能指针通过一个模板类auto_ptr来实现,new操作符返回的指针可以交由它来管理,程序员不用再显式的调用delete,这在一定程度上避免了堆内存忘记释放的问题:不过auto_ptr有 ...
- 使用masory
动态更新约束的时候老是提示有多余的约束,我使用update_contraits make_contraits 都不能解决,后来使用了remake_contraits才消除了告警. view pro ...
- OBV_X3
{OBV_X3[背景]考虑到OBV_X03在情况1的时候,采用的是寻找波段线的同价K线,但是由于此种情况下必须使用CONST(C)或通过输入参数CONSTCC设定固定值,无法当前K线的CLOSE同时变 ...
- Twitter OA prepare: even sum pairs
思路:无非就是扫描一遍记录奇数和偶数各自的个数,比如为M和N,然后就是奇数里面选两个.偶数里面选两个,答案就是M(M-1)/2 + N(N-1)/2
- 利用lodop打印控件轻松实现批量打印 (转载http://www.thinkphp.cn/topic/13085.html)
最近在做一个打印程序,要实现批量打印功能,在网上找了很多天,也在tp官网咨询大牛们,对大家的的提议我一一进行了研究,总结如下: 要实现批量打印可以有两个办法: 一是利用专业的报表程序,能实现十分复杂的 ...
- no-siteapp 和 no-transform
简单的说,是禁止转码 . 举个通俗的例子. 你建了一栋房子(网站),百度说我给你做个大门,但是大门上要有我的广告 你不愿意,就建立了一条路叫no-transform 别人去你家走这条路就行了 后来百度 ...