POJ 2823 Sliding Window (线段树/单调队列)
题目不说了,可以用线段树或者单调队列,下面附上代码。
线段树:
#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 (线段树/单调队列)的更多相关文章
- POJ 2823 Sliding Window 线段树
http://poj.org/problem?id=2823 出太阳啦~^ ^被子拿去晒了~晚上还要数学建模,刚才躺在床上休息一下就睡着了,哼,还好我强大,没有感冒. 话说今年校运会怎么没下雨!!!说 ...
- POJ 2823 Sliding Window 线段树区间求和问题
题目链接 线段树区间求和问题,维护一个最大值一个最小值即可,线段树要用C++交才能过. 注意这道题不是求三个数的最大值最小值,是求k个的. 本题数据量较大,不能用N建树,用n建树. 还有一种做法是单调 ...
- POJ 2823 Sliding Window 再探单调队列
重新刷这个经典题,感觉跟以前不一样了,变得更加容易理解了,不讲解了,看代码.注意:要用C++提交,用G++会超时.. 代码: #include <iostream> #include &l ...
- PKU 2823 Sliding Window(线段树||RMQ||单调队列)
题目大意:原题链接(定长区间求最值) 给定长为n的数组,求出每k个数之间的最小/大值. 解法一:线段树 segtree节点存储区间的最小/大值 Query_min(int p,int l,int r, ...
- POJ 2823 Sliding Window + 单调队列
一.概念介绍 1. 双端队列 双端队列是一种线性表,是一种特殊的队列,遵守先进先出的原则.双端队列支持以下4种操作: (1) 从队首删除 (2) 从队尾删除 (3) 从队尾插入 (4) ...
- 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的窗口.现在这个从左边开始向右滑动,每 ...
- 【BZOJ-2892&1171】强袭作战&大sz的游戏 权值线段树+单调队列+标记永久化+DP
2892: 强袭作战 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 45 Solved: 30[Submit][Status][Discuss] D ...
- BZOJ 1012 线段树||单调队列
非常裸的线段树 || 单调队列: 假设一个节点在队列中既没有时间优势(早点入队)也没有值优势(值更大),那么显然不管在如何的情况下都不会被选为最大值. 既然它仅仅在末尾选.那么自然能够满足以上的条件 ...
随机推荐
- FTP协议及工作原理详解
1. FTP协议 什么是FTP呢?FTP 是 TCP/IP 协议组中的协议之一,是英文File Transfer Protocol的缩写. 该协议是Internet文件传送的基础,它由一系列规格说明文 ...
- CityEngine2012(32位)安装
今天下午把CityEngine2012装好了,既然Esri大力推CityEngine作为其三维建模软件,那就学习一下,还好没花多长时间搞定破解版,以前装Erdas,南方CASS,AutoCAD那些该死 ...
- 存储过程及Comm.cs类的创建
2013-09-25 13:08:59 一.准备工作 首先创建一个数据库,如创建“试用期公务员管理”数据库:再创建一个Comm.cs类,添加代码如下: using System;using Syste ...
- UML类图新手入门级介绍
UML类图新手入门级介绍 举一个简单的例子,来看这样一副图,其中就包括了UML类图中的基本图示法. 首先,看动物矩形框,它代表一个类(Class).类图分三层,第一层显示类的名称,如果是抽象类,则就用 ...
- jQuery Mobile 开发中常见的问题
目录 页面缩放显示问题 页面跳转后样式丢失js失效 跳转时重复调用pageinit方法的解决办法 如何调用loading效果 1页面缩放显示问题 问题描述: 页面似乎被缩小了,屏幕太宽了. 解决办 ...
- 设置Linux时间 同步时间
date命令将日期设置为2014年6月18日 ---- date -s 06/18/14 将时间设置为14点20分50秒 ---- date -s 14:20:50 将时间设置为2014年6月 ...
- jQuery1.9 $.browser 的替代方法
jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support . 在更新的 2.0 版本中,将不再支持 IE 6/7/8. ...
- php中url传递中文字符,特殊危险字符的解决方法
php中的urldecode,base64_encode函数然后再结合自己写的替换函数来进行安全传递url中文字符,特殊危险字符. 需要在url中传递中文字符或是其它的html等特殊字符,似乎总会有各 ...
- 【PHP】phpcms 关联连接修复
function _keylinks($txt, $replacenum = '',$link_mode = 1) { $keywords = $this->data['keywords']; ...
- RouterOS的MikroTik脚本从DNS更新IPSEC端的IP地址
#Script for changing IPSEC address when DNS changes. #Script will iterate through all peers looking ...