• 【模板】deque实现单调队列


    双端队列deque容器:

    关于deque最常用的有这几个函数

    都是成员函数

    双端队列模板题:【洛谷】P2952 [USACO09OPEN]牛线Cow Line

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<deque>
     6 using namespace std;
     7 
     8 int n, cnt;
     9 deque<int> q;
    10 
    11 int main() {
    12     scanf("%d
    ", &n);
    13     char s[21];
    14     for(int i=1; i<=n; ++i) {
    15         gets(s);
    16         if(s[0] == 'A')
    17             if(s[2] == 'L') q.push_front(++cnt);
    18             else q.push_back(++cnt);
    19         if(s[0] == 'D') {
    20             int m = 0, j = 1;
    21             while(s[j]<'0' || s[j]>'9') ++j;
    22             while(s[j]>='0' && s[j]<='9')
    23                 m = (m << 3) + (m << 1) + s[j] - 48, ++j;
    24             while(m--) {
    25                 if(s[2] == 'L') q.pop_front();
    26                 else q.pop_back();
    27             }
    28         }
    29 
    30     }
    31     deque<int>::iterator it;
    32     for(it=q.begin(); it!=q.end(); ++it)
    33         printf("%d
    ", *it);
    34 }
    P2952 [USACO09OPEN]牛线Cow Line

    单调队列deque容器实现:

    设一个数组a,可以修改某一个元素的值,求a中所有元素的最小(大)值

    每次从头扫到尾的时间复杂度O(n2)太高了,st表虽然是O(1)查询但不支持修改

    可以使用线段树O(n log2 n)来做但复杂度还是不够优秀,常数还大

    单调队列登场了:

    每次加入双端队列尾一个元素num时,从队尾将队列中所有比num大的元素都pop出去,再push_back(num)

    这样就能实现单调队列了。

    单调队列模板题:【洛谷】P1440 求m区间内的最小值

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<deque>
     5 using namespace std;
     6 
     7 const int MAXN = 2000000 + 1;
     8 
     9 int n, m;
    10 int a[MAXN];
    11 deque<int> q;
    12 
    13 inline int read() {
    14     int x=0, f=1; char ch=getchar();
    15     while(ch<'0' || ch>'9') {
    16         if(ch == '-') f = -1;
    17         ch = getchar();
    18     }
    19     while(ch>='0' && ch<='9')
    20         x=(x<<3)+(x<<1)+ch-48, ch=getchar();
    21     return x * f;
    22 }
    23 
    24 int main() {
    25     n = read(), m = read();
    26     for(int i=1; i<=n; ++i) a[i] = read();
    27     puts("0");
    28     for(int i=1; i<n; ++i) {
    29         if(i>m && q.front()==a[i-m]) q.pop_front();
    30         while(!q.empty() && q.back()>a[i]) q.pop_back();
    31         q.push_back(a[i]);
    32         printf("%d
    ", q.front());
    33     }
    34 }
    P1440 求m区间内的最小值

    单调队列优化DP:

    在用单调队列优化DP的时候,每次除维护序列的单调性外,还需要把队首已经没有用的元素pop_front()

    能够用单调队列优化的DP一般都长成这个样子:

      f[i] = max/min{f[k]} + ...

      1 ≤ k < i

    而优化的其实是求最值的过程:O(n)优化到了O(1).

  • 相关阅读:
    web项目优化
    mysql 优化笔记
    Java 调用 google 翻译
    Git回滚merge操作
    mybatis 批量插入 返回主键id
    idea tomcat debug 失效
    mysql 常用语句
    xstream 解析xml报文
    activeMQ 讲解及实战
    linux svn apache
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/9071069.html
Copyright © 2020-2023  润新知