何为单调队列?

单调队列是一个队列(废话)

而且必须同时满足下标单调和值单调两个单调特性。

跟优先队列不同,优先队列直接使用堆(heap)来实现,如何删去特定下标元素?不明。

本人喜欢用单调队列存下标,这样比存值不知道高到哪里去了。

新来一个元素,进队。之后特判长度有没有超过。超过则把最前面的元素出队。

之后,如果不满足性质,就把前面的元素顶掉,直到满足性质为止。

然后才可以把队首元素拿来用。

有几个很坑的地方,具体看代码注释。

(为什么top是队尾而tail是队首?laughcry)

例题:洛谷P1886,高级模板题。还有一道剧毒的P2216。(排版很奇怪,都怪反人类的博客园☺)

AC代码:

 1 #include <cstdio>
 2 const int N = 1000010;
 3 
 4 int pl[N], l_t, l_h = 1, ansl[N];
 5 int ps[N], s_t, s_h = 1, anss[N];
 6 int a[N];
 7 
 8 int main() {
 9     int n, k;
10     scanf("%d%d", &n, &k);
11     for(int i = 1; i <= n; i++) {
12         scanf("%d", &a[i]);
13     }
14     for(int i = 1; i <= n; i++) {
15         pl[++l_t] = i;
16         ps[++s_t] = i;
17         if(pl[l_h] + k <= i) {
18             l_h++;
19         }
20         if(ps[s_h] + k <= i) {
21             s_h++;
22         }
23         while(l_t > l_h && a[pl[l_t - 1]] <= a[i]) {
24             l_t--;
25         }
26         while(s_t > s_h && a[ps[s_t - 1]] >= a[i]) {
27             s_t--;
28         }
29         pl[l_t] = i;
30         ps[s_t] = i;
31         ansl[i] = pl[l_h];
32         anss[i] = ps[s_h];
33     }
34     for(int i = k; i <= n; i++) {
35         printf("%d ", a[anss[i]]);
36     }
37     printf("\n");
38     for(int i = k; i <= n; i++) {
39         printf("%d ", a[ansl[i]]);
40     }
41     return 0;
42 }
最新写的P1886

相关文章:

  • 2021-11-17
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-09-29
  • 2021-09-28
  • 2022-12-23
  • 2021-11-22
猜你喜欢
  • 2021-12-08
  • 2021-09-17
  • 2022-02-28
  • 2021-06-04
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案