滑窗模板_双向队列

附上电科算法讲堂  https://www.bilibili.com/video/av23189029?t=641  (感谢那些讲课的美好的人们)

/*
*  注:  还有少许细节问题可能需要注意: 例如 总长度小于窗口长度的情况.
*       和rGetMax  rGetMin 下标小于零的情况 没有pass..
*/

class HuaChuang_Max {
public:
    struct cnobe {
        int id;
        int val;
        cnobe () {}
        cnobe (int _id, int _val) : id(_id), val(_val) {}
    };

    deque<cnobe> cq;

    int GetMax(int date[], int ans[], int sz, int len) {  // [a, b] a>=1 开始滑窗
        int cnt = 0;
        int i;
        while (!cq.empty()) cq.pop_back();
        for (i=1; i<len; ++i) {
            while (!cq.empty() && cq.back().val < date[i])
                    cq.pop_back();
            cq.push_back(cnobe(i, date[i]));
        }
        for (i=len; i<=sz; ++i) {
            while (!cq.empty() && cq.back().val < date[i])
                    cq.pop_back();
            cq.push_back(cnobe(i, date[i]));
            while (i - cq.front().id >= len) cq.pop_front();
            ans[cnt++] = cq.front().val;
        }
        return cnt;
    }

    int GetMin(int date[], int ans[], int sz, int len) {  // [a, b] a>=1 开始滑窗
        int cnt = 0;
        int i;
        while (!cq.empty()) cq.pop_back();
        for (i=1; i<len; ++i) {
            while (!cq.empty() && cq.back().val > date[i])
                    cq.pop_back();
            cq.push_back(cnobe(i, date[i]));
        }
        for (i=len; i<=sz; ++i) {
            while (!cq.empty() && cq.back().val > date[i])
                    cq.pop_back();
            cq.push_back(cnobe(i, date[i]));
            while (i - cq.front().id >= len) cq.pop_front();
            ans[cnt++] = cq.front().val;
        }
        return cnt;
    }

    int rGetMax(int date[], int ans[], int sz, int len) {  // [a, b] a>=1 开始滑窗
        int cnt = 0;
        int i;
        while (!cq.empty()) cq.pop_back();
        for (i=sz; i>sz-len+2 && i>0; --i) {
            while (!cq.empty() && cq.back().val < date[i])
                    cq.pop_back();
            cq.push_back(cnobe(i, date[i]));
        }
        for (i=sz-len+2; i>0; --i) {
            while (!cq.empty() && cq.back().val < date[i])
                    cq.pop_back();
            cq.push_back(cnobe(i, date[i]));
            while (cq.front().id - i >= len) cq.pop_front();
            ans[i] = cq.front().val;
            cnt++;
        }
        return cnt;
    }

    int rGetMin(int date[], int ans[], int sz, int len) {  // [a, b] a>=1 开始滑窗
        int cnt = 0;
        int i;
        while (!cq.empty()) cq.pop_back();
        for (i=sz; i>sz-len+2 && i>0; --i) {
            while (!cq.empty() && cq.back().val > date[i])
                    cq.pop_back();
            cq.push_back(cnobe(i, date[i]));
        }
        for (i=sz-len+2; i>0; --i) {
            while (!cq.empty() && cq.back().val > date[i])
                    cq.pop_back();
            cq.push_back(cnobe(i, date[i]));
            while (cq.front().id - i >= len) cq.pop_front();
            ans[i] = cq.front().val;
            cnt++;
        }
        return cnt;
    }
}hc;

原文地址:https://www.cnblogs.com/cgjh/p/9394099.html

时间: 2024-08-24 01:29:51

滑窗模板_双向队列的相关文章

【10.7校内测试】【队列滑窗】【2-sat】【贪心+栈二分+线段树(noip模拟好题)】【生日祭!】

比较好想的一道题,直接用队列滑窗,因为扫一遍往队列里加东西时,改变的只有一个值,开桶储存好就行了! #include<bits/stdc++.h> using namespace std; int n, k, r; inline int min(int a, int b) { return a > b ? b : a; } inline int max(int a, int b) { return a > b ? a : b; } int sum[200005], q[200005

双向队列(STL做法)

双向队列 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 想想双向链表--双向队列的定义差不多,也就是说一个队列的队尾同时也是队首:两头都可以做出队,入队的操作. 现在给你一系列的操作,请输出最后队列的状态: 命令格式: LIN X  X表示一个整数,命令代表左边进队操作: RIN X  表示右边进队操作: ROUT LOUT   表示出队操作: 输入 第一行包含一个整数M(M<=10000),表示有M个操作: 以下M行每行包

手机模板_苹果风格 iOS7 X3_X3.1版源码

[模板介绍:三十大功能与特性]:0.[具有蓝.橙.绿.宝石绿.青.酷黑.红.玫瑰红.粉红.紫.商务蓝.灰蓝12种配色],支持无限配色扩展! 支持iOS.Android系统,兼容多种移动终端!1.[支持图片墙瀑布][发帖.回帖等上传多张图片].2.[App化处理]让您的网站更像一个独立的App应用!3.[全局侧边栏滑出面板菜单]酷炫时尚,动感十足!4.支持全局页脚.头部固定导航:5.支持帖子列表样式和图文样式浏览:[注意:1.(iOS6版只具有质感蓝.酷炫黑两种配色):2.(iOS6版不支持图片墙

poj 2905 双向队列(待补充)

Parallel Computer Simulator Description Programs executed concurrently on a uniprocessor system appear to be executed at the same time, but in reality the single CPU alternates between the programs, executing some number of instructions from each pro

deque双向队列

对于双向队列,与队列queue以及vector容器的区别就在于,名字不同,也就是它是双向的,可以从头开始操作,也可以从末尾开始操作. 双向队列的常用方法跟队列queue差不多: 头文件: #include<deque> 函数: 构造/析构 deque<int>q  构造一个空的双向队列 deque<int>q(q1)  构造q,并复制q1 deque<int>q(n)  创建deque,含有n个数据,数据均由缺省构造函数产生 deque<int>

C++ Double Ended Queues(双向队列)

双向队列和向量很相似,但是它允许在容器头部快速插入和删除(就像在尾部一样). Constructors 创建一个新双向队列 Operators 比较和赋值双向队列 assign() 设置双向队列的值 at() 返回指定的元素 back() 返回最后一个元素 begin() 返回指向第一个元素的迭代器 clear() 删除所有元素 empty() 返回真如果双向队列为空 end() 返回指向尾部的迭代器 erase() 删除一个元素 front() 返回第一个元素 get_allocator()

算法学习之基础(背包 列队 栈) 习题1.3.33泛型双向队列

前几天写的.. 1 package gh; 2 3 import java.util.Iterator; 4 5 /** 6 * 泛型双向队列(双向链表实现) 7 * @author ganhang 8 * 9 */ 10 public class Deque<T> implements Iterable<T> { 11 private Node first; 12 private Node last; 13 private int n=0; 14 public Deque(){

[poj 3261]后缀数组+滑窗最小值

题目链接:http://poj.org/problem?id=3261 这个是可以交叉的重复串,所以用height就可以了,但是题目说让重复k次以上,也就是直接做一个k-1长度的滑窗最小值,从这些最小值里取最大即可. 这里其实为了节省空间可以先给数字离散化一下,这样就只有20000了,不过不离散化空间也够用. #include<cstdio> #include<algorithm> #include<cstring> #include<queue> usin

python的collection系列-双向队列和单向队列

单向队列:数据先进先出 双向队列:可进可出 双向队列部分源码: 1 class deque(object): 2 """ 3 deque([iterable[, maxlen]]) --> deque object 4 5 Build an ordered collection with optimized access from its endpoints. 6 """ 7 def append(self, *args, **kwargs