[LG1886]滑动窗口 单调队列
题解:
观察数据范围,这应该是一个复杂度O(n)的题。以最大值为例,考虑单调队列,维护一个单调递减的队列。从前向后扫,每次答案取队首,如果后面进入的比前面大,那么就弹出前面的数,因为是从前向后扫,所以后面进入的如果比前面的大,那么一定更优,因为要淘汰肯定先淘汰前面的。如果队首已经不在当前窗口内了,那么就弹出,直到合法为止。
维护单调队列时的一个重要原则就是把别人“挤掉”的元素一定要比被挤掉的元素更优,否则可能找不到合法情况or漏掉最优解。注意这一点就很好理解了。
最小值用求最大值相反的操作即可
不知道为什么我以前写代码写那么丑,,,,重新写一份好了。
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 1001000 int n, k, head, tail;
int s[AC];
struct node{
int x, id;
}q[AC]; inline int read()
{
int x = ;char c = getchar(); bool z = false;
while(c > '' || c < '')
{
if(c == '-') z = true;
c = getchar();
}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
if(!z) return x;
else return -x;
} void pre()
{
n = read(), k = read();
for(R i = ; i <= n; i ++) s[i] = read();
} void work1()
{
head = , tail = ;
for(R i = ; i <= n; i ++)
{
while(head <= tail && q[head].id <= i - k) ++ head;
while(s[i] < q[tail].x && head <= tail) -- tail;//可以删完,反正后面要塞进来
q[++tail] = (node){s[i], i};
if(i >= k) printf("%d ", q[head].x);
}
printf("\n");
} void work2()
{
head = , tail = ;
for(R i = ; i <= n; i ++)
{
while(head <= tail && q[head].id <= i - k) ++ head;//,,,前面也可以删完
while(s[i] > q[tail].x && head <= tail) -- tail;//可以删完,反正后面要塞进来
q[++tail] = (node){s[i], i};
if(i >= k) printf("%d ", q[head].x);
}
printf("\n");
} int main()
{
freopen("in.in", "r", stdin);
pre();
work1();
work2();
fclose(stdin);
return ;
}
当然如果你喜欢简短的代码,且不在意常数问题,你也可以这么写:
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 1001000 int n, k, head, tail;
int s[AC];
struct node{ int x, id;} q[AC]; void cal(int t)
{
head = , tail = ;
for(R i = ; i <= n; i ++)
{
while(head <= tail && q[head].id <= i - k) ++ head;
while(s[i] < q[tail].x && head <= tail) -- tail;//可以删完,反正后面要塞进来
q[++tail] = (node){s[i], i};
if(i >= k) printf("%d ", q[head].x * t);
}printf("\n");
} int main()
{
scanf("%d%d", &n, &k);
for(R i = ; i <= n; i ++) scanf("%d", &s[i]);
cal();
for(R i = ; i <= n; i ++) s[i] = -s[i];
cal(-);
return ;
}
[LG1886]滑动窗口 单调队列的更多相关文章
- luoguP1886 滑动窗口 [单调队列]
题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...
- [POJ2823]Sliding Window 滑动窗口(单调队列)
题意 刚学单调队列的时候做过 现在重新做一次 一个很经典的题目 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗 ...
- POJ 2823 滑动窗口 单调队列
https://vjudge.net/problem/POJ-2823 中文:https://loj.ac/problem/10175 题目 给一个长度为 $N$ 的数组,一个长为 $K$ 的滑动窗体 ...
- [洛谷P1886]滑动窗口 (单调队列)(线段树)
---恢复内容开始--- 这是很好的一道题 题目描述: 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口. 现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的 ...
- [Luogu P1886]滑动窗口--单调队列入门
题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...
- AcWing 154. 滑动窗口 单调队列
地址 https://www.acwing.com/problem/content/description/156/ 输入格式 输入包含两行. 第一行包含两个整数n和k,分别代表数组长度和滑动窗口的长 ...
- 洛谷 P1886 滑动窗口(单调队列)
题目链接 https://www.luogu.org/problemnew/show/P1886 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始 ...
- cogs 495. 滑动窗口 单调队列
495. 滑动窗口 ★★ 输入文件:window.in 输出文件:window.out 简单对比时间限制:2 s 内存限制:256 MB [问题描述] 给你一个长度为N的数组,一个长为 ...
- POJ 2823 滑动窗口 单调队列模板
我们从最简单的问题开始: 给定一个长度为N的整数数列a(i),i=0,1,...,N-1和窗长度k. 要求: f(i) = max{a(i-k+1),a(i-k+2),..., a(i)},i = 0 ...
随机推荐
- 基于ftp服务的三种登录方式及其相关的访问控制和优化
ftp(简单文件传输协议),是一种应用广泛的网络文件传输协议和服务,占用20和21号端口,主要用于资源的上传和下载. 在linux对于ftp同widows一样具有很多的种类,这里主要介绍vsfptd( ...
- Hadoop(13)-MapReduce框架原理--Job提交源码和切片源码解析
1.MapReduce的数据流 1) Input -> Mapper阶段 这一阶段的主要分工就是将文件切片和把文件转成K,V对 输入源是一个文件,经过InputFormat之后,到了Mapper ...
- 阅读《大型网站技术架构》,并结合"重大需求征集系统"有感
今天阅读了<大型网站技术架构:核心原理与案例分析>的第五.六.七章.这三张主要是讲述了一个系统的可用性.伸缩性和可扩展性.而根据文中所讲述的,一个系统的可用性主要是体现在这个系统的系统服务 ...
- u-boot.bin生成过程分析
ELF格式“u-boot”文件的生成规则如下,下面对应Makefile的执行过程分别分析各个依赖. $(obj)u-boot: depend version $(SUBDIRS) $(OBJS) $( ...
- Awakening Your Senses【唤醒你的感觉官能】
Awakening Your Senses Give youself a test. Which way is the wind blowing? How many kinds of wildflow ...
- C# 实现窗口无边框,可拖动效果
#region 无边框拖动效果 [DllImport("user32.dll")]//拖动无窗体的控件 public static extern bool ReleaseCaptu ...
- Verilog 初级入门概念
首先我们要理解两种变量类型 Net Type(连线型)和 Register Type (寄存器型): Net Type(连线型),从名字上理解就是“导线”呗,导线的这头和导线的另一头始终是直接连通的, ...
- Java线程和多线程(九)——死锁
Java中的死锁指的就是一种多于两个线程永远阻塞的特殊状况.Java中的死锁状态至少需要多于两个线程以及资源的时候才会产生.这里,我写了一个产生死锁的程序,并且讲下如何分析死锁. 首先来看一下产生死锁 ...
- 4,由spring展开的串烧
一.什么是Spring框架?Spring框架有哪些主要模块? Spring框架是一个为Java应用程序的开发提供了综合.广泛的基础性支持的Java平台.Spring帮助开发者解决了开发中基础性的问题, ...
- 30分钟 带你浅入seajs源码
上个星期写了浅入requirejs的, 大家都知道 require是AMD规范(Asynchronous Module Definition) 来 今天我们一起看看 CMD规范(Common Mo ...