From c62258627701c691df320f018bd354918328598e Mon Sep 17 00:00:00 2001 From: hanyixuanten Date: Wed, 28 Oct 2026 10:53:45 +0000 Subject: [PATCH] new file: P1886.cpp --- P1886.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ P1886.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 P1886.cpp create mode 100644 P1886.md diff --git a/P1886.cpp b/P1886.cpp new file mode 100644 index 0000000..3c6f422 --- /dev/null +++ b/P1886.cpp @@ -0,0 +1,40 @@ +#include +using namespace std; +int n, k; +int a[1000005]; +pair minq[4000005]; +pair maxq[4000005]; +int lq = 1, rq = 0; +int lqq = 1, rqq = 0; +void push(pair now) { + while(lq <= rq && maxq[lq].second <= now.second - k) ++lq; + while(lq <= rq && maxq[rq].first < now.first) --rq; + maxq[++rq] = now; + + while(lqq <= rqq && minq[lqq].second <= now.second - k) ++lqq; + while(lqq <= rqq && minq[rqq].first > now.first) --rqq; + minq[++rqq] = now; +} +int maxx[1000005]; +int minn[1000005]; +int main() { + scanf("%d%d", &n, &k); + for(int i = 1; i <= n; ++i) { + scanf("%d", &a[i]); + } + for(int i = 1; i <= k; ++i) { + push(make_pair(a[i], i)); + } + maxx[1] = maxq[lq].first; + minn[1] = minq[lqq].first; + for(int l = 2; l + k - 1 <= n; ++l) { + int r = l + k - 1; + push(make_pair(a[r], r)); + maxx[l] = maxq[lq].first; + minn[l] = minq[lqq].first; + } + for(int i = 1; i + k - 1 <= n; ++i) printf("%d ", minn[i]); + printf("\n"); + for(int i = 1; i + k - 1 <= n; ++i) printf("%d ", maxx[i]); + return 0; +} \ No newline at end of file diff --git a/P1886.md b/P1886.md new file mode 100644 index 0000000..31428f8 --- /dev/null +++ b/P1886.md @@ -0,0 +1,51 @@ +# P1886 【模板】单调队列 / 滑动窗口 + +## 题目描述 + +有一个长为 $n$ 的序列 $a$,以及一个大小为 $k$ 的窗口。现在这个窗口从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最小值和最大值。 + +例如,对于序列 $[1,3,-1,-3,5,3,6,7]$ 以及 $k = 3$,有如下过程: + +$$\def\arraystretch{1.2} +\begin{array}{|c|c|c|}\hline +\textsf{窗口位置} & \textsf{最小值} & \textsf{最大值} \\ \hline +\verb![1 3 -1] -3 5 3 6 7 ! & -1 & 3 \\ \hline +\verb! 1 [3 -1 -3] 5 3 6 7 ! & -3 & 3 \\ \hline +\verb! 1 3 [-1 -3 5] 3 6 7 ! & -3 & 5 \\ \hline +\verb! 1 3 -1 [-3 5 3] 6 7 ! & -3 & 5 \\ \hline +\verb! 1 3 -1 -3 [5 3 6] 7 ! & 3 & 6 \\ \hline +\verb! 1 3 -1 -3 5 [3 6 7]! & 3 & 7 \\ \hline +\end{array} +$$ + +## 输入格式 + +输入一共有两行,第一行有两个正整数 $n,k$;\ +第二行有 $n$ 个整数,表示序列 $a$。 + +## 输出格式 + +输出共两行,第一行为每次窗口滑动的最小值; +第二行为每次窗口滑动的最大值。 + +## 输入输出样例 #1 + +### 输入 #1 + +``` +8 3 +1 3 -1 -3 5 3 6 7 +``` + +### 输出 #1 + +``` +-1 -3 -3 -3 3 3 +3 3 5 5 6 7 +``` + +## 说明/提示 + +【数据范围】 +对于 $50\%$ 的数据,$1 \le n \le 10^5$; +对于 $100\%$ 的数据,$1\le k \le n \le 10^6$,$a_i \in [-2^{31},2^{31})$。 \ No newline at end of file