[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 ...
随机推荐
- vue入门笔记
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅易于上手,还便于与 ...
- (四)启用HTTPS
安全规范中有一条是要求尽量使用https而弃用http(新Chrome将标记非HTTPS网站为不安全),其实启用https和之前的ipv6改造一样,并不是什么高难度或者工作流繁多的的改造,只需将中间件 ...
- zabbix监控nginx服务状态
nginx需要安装--with-http_stub_status_module模块 $ nginx -V nginx version: nginx/1.12.2 built by gcc 4.8.5 ...
- 批量安装Python第三方库
1.首先在python程序的文件夹内,新建一个文本文档,名字自定义,在文档中输入需要安装的第三方库,并用英文半角逗号隔开. import os def getTxt(): txt = open(&qu ...
- 002---Linux系统目录结构
Linux系统目录结构 一切从根(/)开始,一切皆文件. /bin:存放常用的可执行文件 /sbin:存放常用的可执行文件 家目录:存放用户自己的文件或目录 root用户:/root 普通用户:/ho ...
- Python3 函数return
# def logger(): # f = open("loge.txt","a") # f.write("2017-09-15 exec funct ...
- 【Leetcode】Jewels and Stones
Jewels and Stones Description You're given strings J representing the types of stones that are jewel ...
- [Cracking the Coding Interview] 4.5 Validate BST
Implement a function to check if a binary tree is a binary search tree. 这道题很经典,让我们判断一棵树是不是二叉查找树.但是首先 ...
- 总结Verilog中always语句的使用
always语句包括的所有行为语句构成了一个always语句块.该always语句块从仿真0时刻开始执行其中的行为语句:最后一条执行完成后,再开始执行其中的第一条语句,如此往复循环,直到整个仿真结束. ...
- 炒鸡简单的javaScript的call和apply方法
解释一 作者:杨志 链接:https://www.zhihu.com/question/20289071/answer/14644278 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商 ...