• POJ 2823 Sliding Window 单调队列


    题意很明显,注意用C++提交,不然会超时。

    说说我对单调队列的理解吧。

    其实就是每次都在队头保留了ans。就是每次你想知道第i个位置的答案,每次取出队头元素就OK了。

    然后就是怎么维护了。

    例如要求最大值,那么,队头应该是一个最大值的。所以这个队列是单调递减的,每次插入a[i]的时候,维护它单调递减就OK,同时可以把它插入的这个位置后面的值删除了,是没用了。因为a[i]比他们大,而且比他们新。

    关键就是这个新了。

    应该这些元素不在这个窗口的话,那些就属于废弃元素,废弃元素不能被选择,所以队列有第二个参数。id。保留队头元素在数组a[i]的pos。那么当对头的id == i - k的时候。它就是废弃的了。然后把head++即可。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    int n,k;
    const int maxn = 1e6 + 20;
    int a[maxn];
    struct node {
        int val,id;
        node () {}
        node (int vv,int ii) : val(vv), id(ii) {}
    }que[maxn];
    int ans_min[maxn];
    int ans_max[maxn];
    void work ()
    {
        int lenmin = 0, lenmax = 0;
        scanf ("%d%d", &n, &k);
        for (int i = 1; i <= n; ++i) {
            scanf ("%d", a + i);
        }
    //    if (k > n) {
    //        while (1);
    //    }
        que[1].val = a[1];
        que[1].id = 1;
        int head = 1, tail = 1;
        for (int i = 2; i <= k; ++i) { //开始预处理
            while (tail >= head && a[i] >= que[tail].val) --tail;
            ++tail;
            que[tail].val = a[i];
            que[tail].id = i;
        }
        ans_max[++lenmax] = que[head].val;
        for (int i = k + 1; i <= n; ++i) {
            while (tail >= head && a[i] >= que[tail].val) --tail;
            ++tail;
            que[tail].val = a[i]; que[tail].id = i;
            while (head <= tail && que[head].id == i - k) ++head;
            ans_max[++lenmax] = que[head].val;
        }
    
        head = tail = 1;
        que[tail].val = a[1];
        que[tail].id = 1;
        for (int i = 2; i <= k; ++i) {
            while (tail >= head && a[i] <= que[tail].val) --tail;
            ++tail;
            que[tail].val = a[i];
            que[tail].id = i;
        }
        ans_min[++lenmin] = que[head].val;
        for (int i = k + 1; i <= n; ++i) {
           while (tail >= head && a[i] <= que[tail].val) --tail;
           ++tail;
           que[tail].val = a[i]; que[tail].id = i;
           while (head <= tail && que[head].id == i - k) ++head;
           ans_min[++lenmin] = que[head].val; //每次取队头就是ans
        }
        for (int i = 1; i <= lenmin; ++i) {
            printf ("%d ", ans_min[i]);
        }
        printf ("
    ");
        for (int i = 1; i <= lenmax; ++i) {
            printf ("%d ", ans_max[i]);
        }
        printf ("
    ");
        return ;
    }
    
    int main()
    {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        work ();
        return 0;
    }
    View Code
  • 相关阅读:
    JavaScript—飞机大战
    JavaScript—瀑布流
    JavaScript—原生轮播和无缝滚动
    JavaScript—封装animte动画函数
    JavaScript—offset、client、scroll
    JavaScript—对象创建方式
    JavaScript—var lef const区别
    P1352 没有上司的舞会 题解
    P1829 [国家集训队]Crash的数字表格 / JZPTAB 题解
    P2522 [HAOI2011]Problem b 题解
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/5819448.html
Copyright © 2020-2023  润新知