小兔子乖乖,把门开开

#include<bits/stdc++.h> 

using namespace std;

int main( )
{
    //转化为递增的前缀和
    int n,m;
    cin>>n>>m;
    long long a[300000]={0};
    for(int i=1;i<=n;i++){
        cin>>a[i];
        a[i]+=a[i-1];
    }
    deque<long long>q;//存下标
    long long s=-1000000;//注意可能最大伤害是负数,哈哈,真是,没能掉血,还能补血,好东西
    q.push_back(0);
    for(int i=1;i<=n;i++){
        if(!q.empty()&&q.front()<i-m)q.pop_front();//保证滑动窗口的大小最大为m
        s=s>a[i]-a[q.front()]?s:a[i]-a[q.front()];//求窗口的最大值
        while(!q.empty()&&a[q.back()]>=a[i])q.pop_back();//保证单调
        q.push_back(i);
        // for(int j=0;j<q.size();j++){
        //     cout<<q[j]<<' ';
        // }
        // cout<<endl;
    }
    cout<<s;
    return 0;
}

deque常用函数

构造函数

deque<T> dq;:默认构造函数,创建一个空的双端队列。
deque<T> dq(n, value);:创建一个包含 n 个元素,且每个元素都初始化为 value 的双端队列。
deque<T> dq(begin, end);:使用迭代器范围 [begin, end) 初始化双端队列。
添加元素

dq.push_back(value);:在队列尾部添加元素 value。
dq.push_front(value);:在队列头部添加元素 value。
删除元素

dq.pop_back();:删除队列尾部的元素。
dq.pop_front();:删除队列头部的元素。
访问元素

dq.front();:返回队列头部的元素。
dq.back();:返回队列尾部的元素。
dq[index];:通过索引访问元素。
大小和容量

dq.size();:返回队列中元素的数量。
dq.empty();:检查队列是否为空。
dq.clear();:清空队列中的所有元素。
其他操作

dq.insert(position, value);:在指定位置插入元素。
dq.erase(position);:删除指定位置的元素。
dq.assign(n, value);:用 n 个 value 元素替换当前队列的内容。

单调队列

单调队列是一种特殊的数据结构,通常用于解决一些需要维护元素顺序的问题,特别是在滑动窗口或区间查询的场景中。单调队列可以分为单调递增队列和单调递减队列。

常用代码

    deque<int> dq; // 双端队列  
    void push(int value) {  
        // 移除队列中所有小于当前值的元素  
        while (!dq.empty() && dq.back() < value) {  //保证单调
            dq.pop_back();  
        }  
        dq.push_back(value);  
    }  

    // 移除元素  
    void pop(int value) {  
        // 如果弹出的元素是最大值,则从队列中移除  
        if (!dq.empty() && dq.front() == value) {  //可以用来处理窗口大小
            dq.pop_front();  
        }  
    }  

    // 获取当前最大值  
    int max() const {  
        return dq.front(); // 队列的前端是当前窗口的最大值  
    }  

应用场景

  • 滑动窗口最大值/最小值:在给定数组中,计算每个滑动窗口的最大值或最小值。
  • 区间最值查询:在动态数组中快速查询某个区间的最值。

 今天就到这里啦,我们明天再见,✌

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值