惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Attack and Defense Labs
Attack and Defense Labs
T
Threatpost
C
Cybersecurity and Infrastructure Security Agency CISA
H
Hackread – Cybersecurity News, Data Breaches, AI and More
I
Intezer
C
Cyber Attacks, Cyber Crime and Cyber Security
The Register - Security
The Register - Security
量子位
Security Latest
Security Latest
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
MyScale Blog
MyScale Blog
J
Java Code Geeks
Apple Machine Learning Research
Apple Machine Learning Research
Google DeepMind News
Google DeepMind News
WordPress大学
WordPress大学
Spread Privacy
Spread Privacy
Jina AI
Jina AI
博客园 - 【当耐特】
P
Palo Alto Networks Blog
Last Week in AI
Last Week in AI
SecWiki News
SecWiki News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
G
GRAHAM CLULEY
宝玉的分享
宝玉的分享
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
The Blog of Author Tim Ferriss
V
Vulnerabilities – Threatpost
有赞技术团队
有赞技术团队
T
Tor Project blog
H
Hacker News: Front Page
A
Arctic Wolf
NISL@THU
NISL@THU
A
About on SuperTechFans
云风的 BLOG
云风的 BLOG
Engineering at Meta
Engineering at Meta
V
V2EX
N
News and Events Feed by Topic
Webroot Blog
Webroot Blog
Know Your Adversary
Know Your Adversary
P
Privacy International News Feed
I
InfoQ
D
Docker
L
LINUX DO - 最新话题
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
U
Unit 42

gyro永不抽风!

深入理解 Zyzzyva 协议 - gyro永不抽风! 深入理解 PBFT 协议 - gyro永不抽风! 西瓜书 绪论 习题 - gyro永不抽风! PyTorch Data Augmentation 数据增广 - gyro永不抽风! 读论文——YOLO v1 - gyro永不抽风! P1363 幻象迷宫 - DFS - gyro永不抽风! P3572 [POI2014] PTA-Little Bird - DP 单调队列 leetcode 1787 使所有区间的异或结果为零 - DP - 随机跳题计划 P2210 Haywire - 状压 DP VSCode绕开腾讯云COS防盗链 | Markdown魔改过程 - gyro永不抽风! GAN(对抗生成网络)的基本原理以及数学证明 - gyro永不抽风! Canny边缘检测算法(基于OpenCV的Java实现) - gyro永不抽风!
POJ 2823 滑动窗口 单调队列 - 致逝去的青春
博主: gyro永不抽风 · 2022-04-08 · via gyro永不抽风!

Preface

三年前的四月,第一次接触 OI。初三下,小教室里听着 fcx 讲着滑动窗口单调队列,放学后去本部蹭了第一节斜率优化的课,随即拉开了我长达两年的竞赛摆烂之旅。

记忆犹新。第一个注册的 OJ 账户就是 POJ,第一道 AC 的题便是 POJ 2823 滑动窗口。

多年过去,今天再看这个基础中的基础,茫然。只能说这是究极摆烂的下场罢。总之就好好写一下题解。

题面

https://www.luogu.com.cn/problem/P1886

题解

接下来只讨论求最小值的情况。设 $f[i]$ 代表终止于位置 $i$ 的滑动窗口的最小值:

$$
f[i] = \min_{i - k < j \leq i} a[j]
$$

如果暴力做的话时间复杂度为 $O(n^2)$。这里我们需要使用单调队列来优化。

对于最小值:单调队列内的元素值递增,同时 index 也是递增的。为什么这样做?思考一个情况:index 递增的情况下,如果一个 $a[i] > a[j], i < j$,那么在 $i,j$ 都有效的范围内,$a[i]$ 永远不可能作为答案。

这里有一句经典的话:如果一个选手年龄比你小,但却比你强,那你就可以退役了。我们把 index 比作出生年份,$a[]$ 比作能力,那么这句话就维护了一个求最大值的单调队列。

接下来是代码中需要注意的一些问题:

  • head, tail 不是左闭右开,而是 $[head, tail]$。这样做的原因是访问 headtail 的元素就可以简单的:q[head], q[tail]
  • 队列里存的是 index (pos)

注意:第二个 while 可以修改为 if,因为每次 i ++q 内的 pos 递增,写成 while 是习惯。

代码

#include <iostream>

using namespace std;

const int maxn = 1e6+5;
int n, k, a[maxn], q[maxn], head, tail;

int main() {
    cin >> n >> k;
    for (int i = 1; i <= n; i ++) cin >> a[i];
    // min
    head = 1, tail = 0;
    for (int i = 1; i <= n; i ++) {
        while (head <= tail && a[i] <= a[q[tail]]) tail --;
        q[++ tail] = i;
        while (head < tail && q[head] <= i - k) head ++;
        if (i >= k) cout << a[q[head]] << " ";
    } cout << endl;
    // max
    head = 1, tail = 0;
    for (int i = 1; i <= n; i ++) {
        while (head <= tail && a[i] >= a[q[tail]]) tail --;
        q[++ tail] = i;
        while (head < tail && q[head] <= i - k) head ++;
        if (i >= k) cout << a[q[head]] << " ";
    } cout << endl;
    return 0;
}

赞赏作者